प्रयोगकर्ता:SM7/XFDcloser.js: रिवीजन सभ के बीचा में अंतर

Content deleted Content added
Maintenance: mw:RL/MGU - Updated deprecated module name
updated version from enwiki
लाइन 1:
/***************************************************************************************************
XFDcloser --- by Evad37
- See [[User:Evad37/XFDcloser]] for installation, documentation, and important information
Localized for bh.wikipedia --- by SM7
- Licencing and attribution:
-------------------------------------------------------------------------------
https://en.wikipedia.org/wiki/User:Evad37/XFDcloser#Licencing_and_attribution
> A script that assists in closing AFD, CFD, FFD, MFD, RFD, and TFD discussions
***************************************************************************************************/
--------------------------------------------------------------------------------
/* jshint esversion: 5, laxbreak: true, undef: true, eqnull: true, maxerr: 3000 */
* See [[User:SM7/XFDcloser]] for installation details and documentation
/* globals console, document, window, $, mw, importStylesheet, OO, extraJs, Morebits */
--------------------------------------------------------------------------------
* Version 3.3.2
* See page history for change log
--------------------------------------------------------------------------------
* IMPORTANT NOTE:
You are responsible for any edits/actions performed using XFDcloser! Please
make sure you understand relevant Wikipedia policies and procedures, and use
this tool accordingly.
(Some pertinent pages are: [[WP:CON]], [[WP:CLOSE]], [[WP:NAC]])
--------------------------------------------------------------------------------
* Licencing note:
Originally published on the English Wikipedia at
< https://en.wikipedia.org/wiki/User:Evad37/XFDcloser.js > ( and/or
< https://en.wikipedia.org/wiki/User:Evad37/XFDcloser/sandbox.js > and/or
< https://en.wikipedia.org/wiki/User:Evad37/XFDcloser/v3.js > )
and available under Creative Commons Attribution-ShareAlike 3.0 Unported
License (CC BY-SA 3.0) < https://creativecommons.org/licenses/by-sa/3.0/ > and
GNU Free Documentation License (GFDL) < http://www.gnu.org/copyleft/fdl.html >
* Attribution note:
This script incorporates code derived from, and is a direct
replacement for, these other scripts also written by Evad37:
- https://en.wikipedia.org/wiki/User:Evad37/CFDcloser.js
- https://en.wikipedia.org/wiki/User:Evad37/FFDcloser.js
- https://en.wikipedia.org/wiki/User:Evad37/TFDcloser.js
Futhermore, it incorporates code copied/derived from:
- https://en.wikipedia.org/wiki/User:Mr.Z-man/closeAFD2.js
- https://en.wikipedia.org/wiki/MediaWiki:Gadget-twinkleunlink.js
- https://en.wikipedia.org/wiki/MediaWiki:Gadget-morebits.js
Further notes:
- See these pages' "History" pages for their authors.
- All of the these pages are also published on Wikipedia, and thus also
available under the terms of the CC BY-SA 3.0 license and GFDL
--------------------------------------------------------------------------------
Have fun, and happy editing! - SM7
*******************************************************************************/
/* <nowiki> */
 
var XFDC_VERSION = "3.14.0";
 
// Record script start time ASAP
var XFDC_START_TIME = new Date();
 
/* ========== Dependencies ====================================================================== */
var getWikipageScript = function getWikipageScript(page) {
// Resource loader modules
var pageUrl = 'https://en.wikipedia.org/w/index.php?title=' + page.replace(/ /g, '_') +
mw.loader.using( ['mediawiki.util', 'mediawiki.api', 'mediawiki.Title', 'mediawiki.util',
'&action=raw&ctype=text/javascript';
'oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows', 'jquery.ui'], function () {
return mw.loader.getScript(pageUrl);
// Load Morebits gadget if not already available
};
if ( window.Morebits == null ) {
 
importScript('MediaWiki:Gadget-morebits.js');
$.when(
importStylesheet( 'MediaWiki:Gadget-morebits.css' );
// Resource loader modules
}
mw.loader.using([
// Load extra.js if not already available
'mediawiki.util', 'mediawiki.api', 'mediawiki.Title',
if ( window.extraJs == null ) {
'oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows', 'jquery.ui'
importScript('User:SM7/extra.js');
]),
}
// Other scripts
// Wait for page load
window.extraJs || getWikipageScript('User:Evad37/extra.js'),
$( function($) {
window.Morebits || getWikipageScript('MediaWiki:Gadget-morebits.js'),
// Stylesheets
importStylesheet( 'User:Evad37/XFDcloser/styles.css' ),
importStylesheet( 'MediaWiki:Gadget-morebits.css' ),
// Page ready
$.ready
).then(function() {
 
 
/* ========== Config ============================================================================ */
Line 65 ⟶ 44:
config.script = {
// Advert to append to edit summaries
advert: ' ([[WP:XFDC|XFDCXFDcloser]])',
version: '3.3.2'XFDC_VERSION
};
// MediaWiki configuration values
Line 74 ⟶ 53:
'wgUserName',
'wgFormattedNamespaces',
'wgMinervaPermissions'
'wgMonthNames'
] );
 
/* --------- Quick checks that script should be running ----------------------------------------- */
if ( /(?:\?|&)(?:action|diff|oldid)=/.test(window.location.href) ) {
// Page is in edit, history, diff, or oldid mode
console.log('[XFDcloser] पन्ना संपादन, इतिहास, अंतर, भा ओल्डआइडी मोड में बा');
return;
}
 
if (
-1 === $.inArray('extendedconfirmed', !config.mw.wgUserGroups.includes('extendedconfirmed') &&
-1 === $.inArray('sysop', !config.mw.wgUserGroups.includes('sysop')
) {
// User is not extendedconfirmed or sysop
console.log('[XFDcloser] प्रयोगकर्ता प्रबंधक भा एक्सटेंडकन्फर्म ना बाड़ें');
return;
}
 
var xfdpage_regex = /(हटावे_खातिर_लेख\/|हटावे_खातिर_बिबिधMiscellany_for_deletion|विकिपीडियाUser:विकिप्रोजेक्ट_हटावल_छंटाईCyberbot_I\/AfD's_requiring_attention|Wikipedia:WikiProject_Deletion_sorting\/(?!(Flat|Compact)$)|चर्चा_खातिर_(श्रेणीCategories|फाइलFiles|टेम्पलेटTemplates|अनुप्रेषणRedirects)_for_discussion(?!\/(Working|Holding_cell|Speedy)))(?!\/?Administrator_instructions$)/;
if ( !xfdpage_regex.test(config.mw.wgPageName) ) {
// Current page is not an XfD page;
console.log('[XFDcloser] वर्तमान पन्ना हचर्चा पन्ना ना बाटे');
return;
}
 
/* --------- CSS rules -------------------------------------------------------------------------- */
mw.util.addCSS(
[ // Inline links
'.xfdc-status { font-size:85%; margin-left:13px; font-weight:normal; }',
'.xfdc-action { margin-left:13px; }',
'.xfdc-action a { cursor:pointer; }',
'.xfdc-qc-cancel { cursor: pointer; border: 1px solid #777; border-radius: 10px;'+
'font-weight: bold; font-size: 90%; color: #777; padding: 0px; margin: 0px 1px; }',
// Dialog
'#xfdc-dialog { background-color:#f0f0f0; padding:0.5em 1em; font-size:110%; }',
'.xfdc-dialog-option { white-space:nowrap; min-width:8em; margin-right:0.3em; '+
'display:block; float:left; }',
'.xfdc-dialog-bracketedOption { white-space:nowrap; margin-left:2em; }',
'.xfdc-dialog-bracketedOption::before, .xfdc-bracketed::before { content: "(\\200A "; }',
'.xfdc-dialog-bracketedOption::after, .xfdc-bracketed::after { content: "\\200A )"; }',
'.xfdc-dialog-container { float:left; max-width:34%; margin-left:0.5em; }',
'.xfdc-dialog-disabled { color:#777; }',
'.xfdc-dialog-actionInfo { border:2px solid #fff; padding:0.2em; margin:0.1em; }',
'.xfdc-dialog-actionInfo > strong { display:block; }',
'.xfdc-dialog-actionInfo > span { margin-left:1.5em; }',
'#closeXFD-interface-buttons > button { margin:1em; }',
'#closeXFD-preview-output { background-color:#fff; border:1px solid #777; '+
'margin-top: 0px; padding:0px 10px; }',
'.closeXFD-errorNote { border:1px solid #ff0000 }',
// Task notices
'.xfdc-notices { width:80%; font-size:95%; padding-left:2.5em; }',
'.xfdc-notices > p { margin:0; line-height:1.1em; }',
'.xfdc-notice-error { color:#D00000; font-size:92% }',
'.xfdc-notice-warning { color:#9900A2; font-size:92% }',
'.xfdc-notice-error::before, .xfdc-notice-warning::before { content: " ["; }',
'.xfdc-notice-error::after, .xfdc-notice-warning::after { content: "]"; }',
'.xfdc-task-waiting { color:#595959; }',
'.xfdc-task-started { color:#0000D0; }',
'.xfdc-task-done { color:#006800; }',
'.xfdc-task-skipped { color:#697000; }',
'.xfdc-task-aborted { color:#C00049; }',
'.xfdc-task-failed { color:#D00000; }',
// Show/hide box
'#XFDcloser-showhide { bottom:0; display:block; position:fixed; right:0; z-index:100; '+
'padding:5px; box-shadow:0 2px 4px rgba(0,0,0,0.5); background-color:#FEF9E6; '+
'border:1px solid #aaa; border-radius:5px; font-size:85% }'
]
.join('\n')
);
 
/* --------- Additional configuration ----------------------------------------------------------- */
config.isMobileSite = window.location.host.includes(".m.") || window.location.search.includes("useformat=mobile");
// Set description for namespace 0
// Set custom version of namespaces with description for namespace 0
config.mw.wgFormattedNamespaces['0'] = 'लेख';
config.mw.namespaces = $.extend({}, config.mw.wgFormattedNamespaces, {0: 'article'});
// Remove empty string from start of wgMonthNames array
// Month names - no longer provided by mw.config, see phab:T219340
config.mw.wgMonthNames = config.mw.wgMonthNames.slice(1);
config.wgMonthNames = ["", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
// Set aliases
// 0-indexed month names (remove "" from start of array)
config.mw.namespaces = config.mw.wgFormattedNamespaces;
config.mw.monthNames = config.mwwgMonthNames.wgMonthNamesslice(1);
// Set sysop status
if ( -1 !== $.inArray('sysop', config.mw.wgUserGroups.includes('sysop') ) {
config.user = {
'isSysop': true,
Line 162 ⟶ 93:
config.user = {
'isSysop': false,
'sig': '<small>[[विकिपीडियाWikipedia:NACD|(गैरnon-प्रबंधकadmin द्वारा समापनclosure)]]</small> ~~~~'
};
}
// Start time, for detecting edit conflicts
config.startTime = XFDC_START_TIME;
// Variables for tracking across multiple discussions
config.track = {
Line 183 ⟶ 116:
});
 
// ========== Convinenance functions ============================================================ */
/* ---------- Settings that are based on the xfd type ------------------------------------------- */
/**
if ( config.mw.wgPageName.includes('विकिपीडिया:हटावे_खातिर_बिबिध') ) {
* Un-escapes some HTML tags (<br>, <p>, <ul>, <li>, <hr>, <strong>, <em>, and <pre>);
//MFD
* turns wikilinks into real links. Ignores anyting within <pre>...</pre> tags.
config.xfd = {
* Input will first be escaped using mw.html.escape() unless specified
type: 'mfd',
* @param {String} text
path: 'विकिपीडिया:हटावे खातिर बिबिध',
* @param {Object} config Configuration options
subpagePath: 'विकिपीडिया:हटावे खातिर बिबिध/',
* @config {Boolean} noEscape - do not escape the input first
* @returns {String} unescaped text
*/
var safeUnescape = function(text, config) {
return ( config && config.noEscape && text || mw.html.escape(text) )
// Step 1: unescape <pre> tags
.replace(
/&lt;(\/?pre\s?\/?)&gt;/g,
'<$1>'
)
// Step 2: replace piped wikilinks with real links (unless inside <pre> tags)
.replace(
/\[\[([^\|\]]*?)\|([^\|\]]*?)\]\](?![^<]*?<\/pre>)/g,
'<a href="' + mw.util.getUrl('$1') + '" target="_blank">$2</a>'
)
// Step 3: replace other wikilinks with real links (unless inside <pre> tags)
.replace(
/\[\[([^\|\]]+?)]\](?![^<]*?<\/pre>)/g,
'<a href="' + mw.util.getUrl('$1') + '" target="_blank">$1</a>'
)
// Step 4: unescape other tags (unless inside <pre> tags)
.replace(
/&lt;(\/?(?:br|p|ul|li|hr|strong|em)\s?\/?)&gt;(?![^<]*?<\/pre>)/g,
'<$1>'
);
};
 
var formatErrorMessage = function(details) {
var type = details && details.type || 'Script';
var error = details && details.error || 'Unknown error';
var message = ( details.message )
? ' - ' + safeUnescape(details.message)
: '';
 
return type + ' error: ' + error + message;
};
 
// TODO: how to pass in a message.... or maybe this should just return {type:..., error:...} objects?
var formatApiError = function(code, jqxhr, message) {
if ( code === 'http') {
var httpError = ( jqxhr.textStatus === 'error')
? jqxhr.xhr.status
: jqxhr.textStatus;
return formatErrorMessage({
type: 'HTTP',
error: httpError,
message: message
});
}
 
if ( code === 'okay-but-empty' ) {
return formatErrorMessage({
type: 'Server',
error: 'Got an empty response from the server'
});
}
 
return formatErrorMessage({
type: 'API',
error: code,
message: message
});
};
 
/* ========== XfdVenue class ====================================================================
Each instance represents an XfD venue, with properties/function specific to that venue
---------------------------------------------------------------------------------------------- */
// Constructor
var XfdVenue = function(type, settings) {
this.type = type;
for ( var key in settings ) {
this[key] = settings[key];
}
};
// ---------- XfdVenue prototype --------------------------------------------------------------- */
XfdVenue.prototype.hasNomTemplate = function(wikitext) {
var pattern = new RegExp(this.regex.nomTemplate);
return pattern.test(wikitext);
};
XfdVenue.prototype.removeNomTemplate = function(wikitext) {
var pattern = new RegExp(this.regex.nomTemplate);
var matches = wikitext.match(pattern);
if ( !matches ) {
return wikitext;
}
if ( matches.length > 1 ) {
throw new Error('Multiple nomination templates on page');
}
return wikitext.replace(pattern, '');
};
XfdVenue.prototype.updateNomTemplateAfterRelist = function(wikitext, today, sectionHeader) {
var matches = wikitext.match(this.regex.relistPattern);
if ( !matches ) {
return wikitext;
}
if ( matches.length > 1 ) {
throw new Error('Multiple nomination templates on page');
}
return wikitext.replace(
this.regex.relistPattern,
this.wikitext.relistReplace
.replace("__TODAY__", today)
.replace("__SECTION_HEADER__", sectionHeader)
);
};
// ---------- Venue-specific instances ----------------------------------------------------------- */
// MFD
XfdVenue.Mfd = function() {
var venue = new XfdVenue('mfd', {
path: 'Wikipedia:Miscellany for deletion',
subpagePath: 'Wikipedia:Miscellany for deletion/',
ns_number: null,
html: {
Line 197 ⟶ 241:
},
wikitext: {
closeTop: "{{subst:Mfd top|}} '''__RESULT__'''}}__TO_TARGET____RATIONALE__ __SIG__",
closeBottom: "{{subst:Mfd bottom}}",
oldXfd: "{{Old MfD |date=__DATE__ |result='''__RESULT__''' |page=__SUBPAGE__}}"+
Line 203 ⟶ 247:
mergeFrom: "{{mfd-mergefrom|__NOMINATED__|__DEBATE__|__DATE__}}\n",
mergeTo: "{{mfd-mergeto|__TARGET__|__DEBATE__|__DATE__|__TARGETTALK__}}\n",
alreadyClosed: "{{#ifeq:{{FULLPAGENAME}}|विकिपीडियाWikipedia:हटावेMiscellany खातिरfor बिबिधdeletion|"+
"{{collapse bottom}}|}}"
},
regex: {
nomTemplate: /(?:<noinclude>\s*)?(?:{{mfd[^}}]*}}|<span id="mfd".*?<\/span>&nbsp;\[\[श्रेणीCategory:हटावेMiscellaneous खातिरpages बिबिधfor पन्नाdeletion\|?.*\]\]\s*)(?:\s*<\/noinclude>)?/gi
},
fn: {
sectionCalc: function() { return 2; }
}
});
return venue;
};
 
// CFD
} else if ( config.mw.wgPageName.includes('चर्चा_खातिर_श्रेणी/') ) {
XfdVenue.Cfd = function() {
//CFD
var venue = new XfdVenue('cfd', {
config.xfd = {
path: 'Wikipedia:Categories for discussion/Log/',
type: 'cfd',
ns_number: [14],
path: 'विकिपीडिया:चर्चा खातिर श्रेणी/लॉग/',
ns_number: 14,
html: {
head: 'h4',
Line 231 ⟶ 273:
oldXfd: "{{Old CfD |__SECTION__ |date=__DATE__ |action=__ACTION__ "+
"|result=__RESULT__}}\n",
alreadyClosed: "<!-- Template:Cfd top -->" ,
relistReplace: " full|day=__DAY__|month=__MONTH__|year=__YEAR__",
},
fnregex: {
nomTemplate: /<!--\s*BEGIN CFD TEMPLATE\s*-->(?:.|\n)+<!--\s*END CFD TEMPLATE\s*-->\n*/gi,
sectionCalc: function(section_number) { return (section_number-1)*2; }
relistPattern: / full\|day\=\d\d?\|month=\w+\|year\=\d{4}/gi
}
});
// Override prototype
venue.updateNomTemplateAfterRelist = function(wikitext, today, _sectionHeader) {
var matches = wikitext.match(venue.regex.relistPattern);
if ( !matches ) {
return wikitext;
}
if ( matches.length > 1 ) {
throw new Error('Multiple nomination templates on page');
}
var todayParts = today.split(' ');
return wikitext.replace(
venue.regex.relistPattern,
venue.wikitext.relistReplace
.replace("__DAY__", todayParts[2])
.replace("__MONTH__", todayParts[1])
.replace("__YEAR__", todayParts[0])
)
.replace( // {{cfc}} is a bit different to the other CFD nomination template
/\'\'\'\[\[Wikipedia\:Categories for discussion\/Log\/\d{4} \w+ \d{1,2}\#/,
"'''[[Wikipedia:Categories for discussion/Log/" + today + "#"
);
};
return venue;
};
 
// FFD
} else if ( config.mw.wgPageName.includes('चर्चा_खातिर_फाइल') ) {
XfdVenue.Ffd = function() {
//FFD
var venue = new XfdVenue('ffd', {
config.xfd = {
typepath: 'ffdWikipedia:Files for discussion/',
ns_number: [6],
path: 'विकिपीडिया:चर्चा खातिर फाइल/',
ns_number: 6,
ns_unlink: ['0', '10', '100', '118'], // main, Template, Portal, Draft
html: {
Line 263 ⟶ 330:
nomTemplate: /{{ffd[^}}]*}}/gi,
relistPattern: /{{\s*ffd\s*\|\s*log\s*=\s*[^|}}]*/gi
},
fn: {
sectionCalc: function(section_number) { return (section_number-1)*2; }
}
});
return venue;
};
 
// TFD
} else if ( config.mw.wgPageName.includes('चर्चा_खातिर_टेम्पलेट') ) {
XfdVenue.Tfd = function() {
//TFD
var venue = new XfdVenue('tfd', {
config.xfd = {
path: 'Wikipedia:Templates for discussion/Log/',
type: 'tfd',
subpagePath: 'Wikipedia:Templates for discussion/',
path: 'विकिपीडिया:चर्चा खातिर टेम्पलेट/लॉग/',
ns_number: [10, 828],
subpagePath: 'विकिपीडिया:चर्चा खातिर टेम्पलेट/',
ns_number: 10,
html: {
head: 'h4',
Line 287 ⟶ 352:
oldXfd: "{{oldtfdfull|date= __DATE__ |result=__RESULT__ |disc=__SECTION__}}\n",
pagelinks: "* {{tfd links|__PAGE__}}\n",
relistReplace: "विकिपीडियाWikipedia:चर्चाTemplates खातिरfor टेम्पलेटdiscussion/लॉगLog/__TODAY__#",
alreadyClosed: "<!-- Tfd top -->"
},
regex: {
nomTemplate: /(?:<noinclude>[\n\s]*)?{{(?:Template for discussion|Tfm)\/dated[^{}]*(?:{{[^}}]*}}[^}}]*)*?}}(?:[\n\s]*<\/noinclude>)?(\n)?/gi,
relistPattern: /विकिपीडियाWikipedia:चर्चाTemplates(_|\s){1}खातिरfor(_|\s){1}टेम्पलेटdiscussion\/लॉगLog\/\d{4}(_|\s){1}\w*(_|\s){1}\d{1,2}#(?=[^}]*}{2})/gi
},
fn: {
sectionCalc: function(section_number) { return (section_number-1)*2; }
},
holdingCellSectionNumber: {
Line 311 ⟶ 373:
"merge-meta": 10
}
});
// Override prototype
venue.removeNomTemplate = function(wikitext) {
var pattern = new RegExp(venue.regex.nomTemplate);
var matches = wikitext.match(pattern);
if ( !matches ) {
return wikitext;
}
if ( matches.length > 1 ) {
throw new Error('Multiple nomination templates on page');
}
var tags = pattern.exec(wikitext);
if ( !tags ) {
return wikitext;
}
var logical_xor = function(first, second) {
return (first ? true : false) !== (second ? true : false);
};
var unbalancedNoincludeTags = logical_xor(tags[1], tags[2]);
var replacement = ( unbalancedNoincludeTags ) ? "$1$2" : "";
return wikitext.replace(pattern, replacement);
};
venue.updateNomTemplateAfterRelist = function(wikitext, today, sectionHeader) {
var matches = wikitext.match(venue.regex.relistPattern);
if ( !matches ) {
return wikitext;
}
if ( matches.length > 1 ) {
throw new Error('Multiple nomination templates on page');
}
return wikitext.replace(
venue.regex.relistPattern,
venue.wikitext.relistReplace
.replace("__TODAY__", today)
.replace("__SECTION_HEADER__", sectionHeader)
);
};
return venue;
};
 
// RFD
} else if ( config.mw.wgPageName.includes('चर्चा_खातिर_अनुप्रेषण') ) {
XfdVenue.Rfd = function() {
//RFD
var venue = new XfdVenue('rfd', {
config.xfd = {
type: 'rfd',
path: 'Wikipedia:Redirects for discussion/Log/',
path: 'विकिपीडिया:चर्चा खातिर अनुप्रेषण/लॉग/',
ns_number: null,
html: {
Line 329 ⟶ 429:
oldXfd: "{{Old RfD |date={{subst:date|__FIRSTDATE__}} |result='''__RESULT__'''"+
" |page=__DATE__#__SECTION__}}\n",
alreadyClosed: "<!-- Template:Rfd top-->" ,
relistReplace: "#invoke:RfD||2=__SECTION_HEADER__|"
},
regex: {
nomTemplate: /(^\s*{{.*#invoke:RfD(?:.|\n)*?-->\|content=\n?|\n?<!-- Don't add anything after this line.*? -->\n}}|\[\[Category:Temporary maintenance holdings\]\]\n?)/g,
fullNomTemplate: /(^\s*{{.*#invoke:RfD(?:.|\n)*?<!-- Don't add anything after this line.*? -->\n}}|\[\[Category:Temporary maintenance holdings\]\]\n?)/g,
relistPattern: /#invoke:RfD\|\|\|/gi
},
});
fn: {
// Override prototype
sectionCalc: function(section_number) { return (section_number-1)*2; }
venue.removeNomTemplate = function(wikitext) {
}
var pattern = new RegExp(venue.regex.nomTemplate);
return wikitext.replace(pattern, '');
};
return venue;
};
 
// AFD
} else if (
XfdVenue.Afd = function(transcludedOnly) {
/(हटावे_खातिर_लेख|विकिपीडिया:विकिप्रोजेक्ट_हटावल_छँटाई)/
var venue = new XfdVenue('afd', {
.test(config.mw.wgPageName)
) {
//AFD
config.xfd = {
type: 'afd',
path: 'विकिपीडियाWikipedia:हटावे खातिर लेख/लॉगLog/',
subpagePath: 'विकिपीडियाWikipedia:हटावे खातिर लेख/',
ns_number: [0], // main
ns_logpages: 4, // Wikipedia
ns_unlink: ['0', '10', '100', '118'], // main, Template, Portal, Draft
Line 368 ⟶ 472:
nomTemplate: /(?:{{[Aa]rticle for deletion\/dated|<!-- Please do not remove or change this AfD message)(?:.|\n)*?}}(?:(?:.|\n)+this\ point -->)?\s*/g
},
transcludedOnly: transcludedOnly
fn: {
});
sectionCalc: function() { return 2; }
return venue;
}
};
 
if ( /(User:Cyberbot_I|विकिपीडिया:विकिप्रोजेक्ट_हटावल_छँटाई)/.test(config.mw.wgPageName) ) {
XfdVenue.newFromPageName = function(pageName) {
config.xfd.transcludedOnly = true;
// Create xfd venue object for this page
var isAfd = /(Articles_for_deletion|User:Cyberbot_I|Wikipedia:WikiProject_Deletion_sorting)/.test(pageName);
var afdTranscludedOnly = /(User:Cyberbot_I|Wikipedia:WikiProject_Deletion_sorting)/.test(pageName);
if ( pageName.includes('Wikipedia:Miscellany_for_deletion') ) {
return XfdVenue.Mfd();
} else if ( pageName.includes('Categories_for_discussion/') ) {
return XfdVenue.Cfd();
} else if ( pageName.includes('Files_for_discussion') ) {
return XfdVenue.Ffd();
} else if ( pageName.includes('Templates_for_discussion') ) {
return XfdVenue.Tfd();
} else if ( pageName.includes('Redirects_for_discussion') ) {
return XfdVenue.Rfd();
} else if ( isAfd ) {
return XfdVenue.Afd(afdTranscludedOnly);
} else {
throw new Error('"' + pageName + '" is not an XFD page');
}
};
 
config.xfd = XfdVenue.newFromPageName(config.mw.wgPageName);
} else {
 
return;
if (window.XFDC_SANDBOX) config = window.XFDC_MAKE_SANDBOX_CONFIG(config); // Adjust some settings if running in sandbox mode
}
 
/* ========== API =============================================================================== */
var API = new mw.Api( {
ajax: {
headers: {
'Api-User-Agent': 'XFDcloser/' + config.script.version +
' ( https://bhen.wikipedia.org/wiki/WP:XFDC )'
}
}
}
} );
 
// Helper functions for processing results
/* ========== Page class ========================================================================
var arrayFromResponsePages = function(response) {
An extended/modified version of the mw.Title class. Each instance
return $.map(response.query.pages, function(page) { return page; });
represents a page nominated in an XfD discussion.
---------------------------------------------------------------------------------------------- */
// Constructor
var Page = function(title) {
try {
mw.Title.call(this, decodeURIComponent(title));
} catch(e) {
throw new Error('"'+title+'" टाइटिल पार्स करे में बिफल');
}
this.exists = null;
this.talk = null;
this.talkExists = null;
};
 
//Constructor with a null return instead of an exception for invalid titles.
Page.newFromTextvar pageFromResponse = function(tresponse) {
return arrayFromResponsePages(response)[0];
if ( mw.Title.newFromText(t) ) {
return new Page(t);
} else {
return null;
}
};
 
API.editWithRetry = function(titles, getParams, transform, onEachSuccess, onEachFail) {
// ---------- Page prototype ------------------------------------------------------------------- */
var processPage = function(page, id, starttime) {
// Inherited from mw.Title
var basetimestamp = page.revisions && page.revisions[0].timestamp;
Page.prototype = Object.create(mw.Title.prototype);
var simplifiedPage = {
Page.prototype.constructor = Page;
pageid: page.pageid,
// Set aliases
missing: page.missing === "",
Page.prototype.getTitle = Page.prototype.getPrefixedText;
redirect: page.redirect === "",
// Additional functions
categories: page.categories,
Page.prototype.getTalk = function() {
ns: page.ns,
if ( this.talk === null ) {
title: page.title,
// talk page not yet set, so set it now
content: page.revisions && page.revisions[0].slots.main["*"]
if ( this.getNamespaceId()%2 === 1 ) {
};
// Page is itself a talk page - set to empty string
return $.when( transform(simplifiedPage) )
this.talk = '';
.then(function(editParams) {
} else {
this.talkvar query = mw$.Title.newFromTextextend( {
this.getMain()action: 'edit',
title: page.title,
this.getNamespaceId()+1
// Protect against errors and conflicts
).getPrefixedText();
assert: 'user',
}
basetimestamp: basetimestamp,
}
starttimestamp: starttime
return this.talk;
}, editParams );
var doEdit = function(isRetry) {
return API.postWithToken('csrf', query)
.then(
function(data) {
if (onEachSuccess) {
onEachSuccess(data);
}
return data.edit;
},
function(code, error) {
if (code === 'http' && !isRetry) {
return doEdit(true);
} else if ( code === 'editconflict' ) {
return doGetQuery(page.title);
}
if (onEachFail) {
onEachFail(code, error, page.title);
}
return $.Deferred().reject(code, error, page.title);
}
);
};
return doEdit();
}, function(code, error) {
if (onEachFail) {
onEachFail(code, error, page.title);
}
return $.Deferred().reject(code, error, page.title);
});
};
var doGetQuery = function(titles, isRetry) {
return API.get(
$.extend(
{
"action": "query",
"format": "json",
"curtimestamp": 1,
"titles": titles,
"prop": "revisions|info",
"rvprop": "content|timestamp",
"rvslots": "main"
},
getParams
)
).then(function(response) {
var starttime = response.curtimestamp;
// Get an array of promises of edits (which may either be resolved or rejected)
var pages = $.map(response.query.pages, function(page, id) {
return processPage(page, id, starttime);
});
// If only for one title, return that promise (which may either be resolved or rejected)
if (!$.isArray(titles)) {
return pages[0];
}
 
// Otherwise, convert the array of promises into a single promise, resolved if all were
// resolved, or rejected with an array of errors of all that failed.
return $.when.apply(
null,
// Force promises to resolve as an object with a `success` key, so that
// $.when will wait for all of them to be resolved or rejected
pages.map(function(page) {
return page.then(
function(success) {
return {success: true};
},
function(code, error, title) {
return {
success: false,
code: code,
error: error,
title: title
};
}
); // end page.then
}) // end page.map
) // end $.when
.then(function() {
var args = Array.prototype.slice.call(arguments);
var errors = args.filter(function(arg) {
return !arg.success;
});
if (errors.length > 0) {
return $.Deferred().reject("write", errors);
}
return true;
});
}, function(code, error) {
if (!isRetry) {
return doGetQuery(titles, true);
}
return $.Deferred().reject("read", code, error);
});
};
return doGetQuery(titles);
};
 
Page.prototype.hasCorrectNamespace = function() {
 
if ( config.xfd.ns_number === null || config.xfd.ns_number === this.getNamespaceId() ) {
var dmyDateString = function(date) {
return true;
return date.getUTCDate().toString() + ' ' +
} else {
config.monthNames[date.getUTCMonth()] + ' ' +
return false;
date.getUTCFullYear().toString();
};
 
/**
* Generates a JS Date object from the text of a timestamp
* @param {String} sigTimestamp in format "`hh`:`mm`, `d` `Month` `yyyy` (UTC)", e.g. "09:42, 11 January 2019 (UTC)"
* @returns {Date|NaN} Date object, or NaN if sigTimestamp could not be parsed
*/
var dateFromSigTimestamp = function(sigTimestamp) {
var pattern = /(\d\d\:\d\d), (\d{1,2}) (\w+) (\d\d\d\d) \(UTC\)/;
var parts = pattern.exec(sigTimestamp);
if ( parts === null ) {
return NaN;
}
var year = parts[4];
var monthIndex = config.wgMonthNames.indexOf(parts[3]);
if ( monthIndex === -1 ) {
return NaN;
}
var month = ( monthIndex < 10 )
? '0' + monthIndex
: monthIndex;
var day = ( parts[2].length === 1 )
? '0' + parts[2]
: parts[2];
var time = 'T' + parts[1] + 'Z';
var iso8601DateString = year + '-' + month + '-' + day + time;
return Date.parse(iso8601DateString) && new Date(iso8601DateString);
};
 
/* ========== Additional functions for working with mw.Title objects ============================ */
var hasCorrectNamespace = function(mwTitleObject) {
return (
config.xfd.ns_number === null ||
config.xfd.ns_number.includes(mwTitleObject.getNamespaceId())
);
};
var setExistence = function(mwTitleObject, exists) {
mw.Title.exist.set(mwTitleObject.toString(), exists);
};
 
/* ========== Multibutton confirm dialog ======================================================== */
 
/** multiButtonConfirm
* @param {Object} config
* @config {String} title Title for the dialogue
* @config {String} message Message for the dialogue. HTML tags (except for <br>, <p>, <ul>,
* <li>, <hr>, and <pre> tags) are escaped; wikilinks are turned into real links.
* @config {Array} actions Optional. Array of configuration objects for OO.ui.ActionWidget
* <https://doc.wikimedia.org/oojs-ui/master/js/#!/api/OO.ui.ActionWidget>.
* If not specified, the default actions are 'accept' (with label 'OK') and 'reject' (with
* label 'Cancel').
* @config {String} size Symbolic name of the dialog size: small, medium, large, larger or full.
* @return {Promise<String>} action taken by user
*/
var multiButtonConfirm = function(config) {
var dialogClosed = $.Deferred();
// Wrap message in a HtmlSnippet to prevent escaping
var htmlSnippetMessage = new OO.ui.HtmlSnippet(
safeUnescape(config.message)
);
 
var windowManager = new OO.ui.WindowManager();
var messageDialog = new OO.ui.MessageDialog();
$('body').append( windowManager.$element );
windowManager.addWindows( [ messageDialog ] );
windowManager.openWindow( messageDialog, {
'title': config.title,
'message': htmlSnippetMessage,
'actions': config.actions,
'size': config.size
} );
windowManager.on('closing', function(_win, promise) {
promise.then(function(data) {
dialogClosed.resolve(data && data.action);
windowManager.destroy();
});
});
 
return dialogClosed.promise();
};
 
/* ========== Discusssion class =================================================================
Each instance represents an XfD discussion.
---------------------------------------------------------------------------------------------- */
//** Constructor
* @param {Object} discussionConfig configuration object:
var Discussion = function(uniqueID, nomPage, sectionHeader, sectionNumber, pageObjects, firstDate) {
* @config {String} id - A unique ID for this discussion (used in various elements' IDs)
this.id = uniqueID;
* @config {String} nomPage - Page where the XFD discussion is taking place; either a dated or
this.nomPage = nomPage;
* name-based subpage
this.sectionHeader = sectionHeader;
* @config {String} sectionHeader - text of the section heading for the XFD discussion
this.sectionNumber = sectionNumber;
* @config {String} sectionNumber - edit section number for the XFD discussion
this.pages = pageObjects; // or false if in in 'basic' mode
* @config {mw.Title[]} pages - pages nominated in the XFD discussion; omit if in basic mode
this.nomDate = null;
this.firstDate* = ( @config {String} firstDate!= null- )first ?timestamp firstDatedate, for :RFD null;discussions
* @config {Boolean} isOld - `true` if discussion has been listed (or relisted) for more than 7 days
this.deferred = {};
* @config {Boolean} isRelisted - `true` if discussion has been relisted
//this.notices = $('<div>')
*
//.attr({'id':uniqueID+'-notices', 'class':'xfdc-notices'})
*/
//.after($('#'+this.id).closest(config.xfd.html.head));
var Discussion = function(discussionConfig) {
var defaultConfig = {
pages: [],
deferred: {} // For later tracking of jQuery Deferred objects
};
$.extend(this, defaultConfig, discussionConfig);
};
// Construct from headline span element
Line 466 ⟶ 757:
var $headlineSpan = $(context);
var $heading = $headlineSpan.parent();
var $statusContainer = config.isMobileSite ? $heading.next() : $heading;
// Fix for "Auto-number headings" preference
Line 471 ⟶ 763:
 
// Get section header
var sectionHeader = $headlineSpan.text().trim();
 
// Check if already closed. Closed AfDs and MfDs have the box above the heading.
if ( /(afd|mfd)/.test(config.xfd.type) && $heading.parent().attr('class') && $heading.parent().attr('class').includes('xfd-closed') ) {
// Skip
return;
Line 486 ⟶ 778:
var sectionlink = $heading.find('.mw-editsection a')
.not('.mw-editsection-visualeditor, .autoCloserButton').attr('href');
if (!sectionlink) {
// Try to find a section link generated by Module:XfD_old.
sectionlink = $heading.next().find(".xfdOldSectionEdit > a").attr("href");
if (!sectionlink) {
// XFDcloser can't work without knowing the nompage and section number, so skip this section.
return;
}
// Add a "T-" so the next check will see this as a transcluded section
sectionlink = sectionlink.replace("section=", "section=T-");
}
var editsection = sectionlink.split('section=')[1].split('&')[0];
var nompage = '';
if ( /T/.test(editsection) ) {
// Section is transcluded from another page
nompage = Pagemw.Title.newFromText(
decodeURIComponent(sectionlink.split("title=")[1].split("&")[0])
).getTitlegetPrefixedText();
if ( -1 !== $.inArray(nompage, [
'Wikipedia:Redirects for discussion/Header',
'विकिपीडिया:चर्चा खातिर अनुप्रेषण/हेडर',
'Wikipedia:Redirect/Deletion reasons',
'विकिपीडिया:अनुप्रेषण/हटावे के कारण',
'Wikipedia:Templates for discussion/Holding cell',
'विकिपीडिया:चर्चा खातिर टेम्पलेट/होल्डिंग सेल'
'Wikipedia:Categories for discussion/Speedy'
])
) {
Line 509 ⟶ 812:
return;
}
nompage = Pagemw.Title.newFromText( config.mw.wgPageName ).getTitlegetPrefixedText();
}
 
var pages=[];
var firstdate = ''firstDate;
 
if ( config.xfd.type === 'cfd' ) {
//CFDs: Nominates pages are the first link of an <li> item in a <ul> list, within a <dl> list
//CFDs have basic closure only
pages = false;$heading
.nextUntil(config.xfd.html.head + ', div.xfd-closed')
.find('dd > ul > li')
.has('b:first-child:contains("Propose ")')
.find('a:first-of-type')
.not('.external')
.map(function() { return mw.Title.newFromText($(this).text()); })
.get();
if ( pages.length === 0 ) {
// Sometimes nominated pages are instead just in a <ul> list, e.g.
// Wikipedia:Categories_for_discussion/Log/2019_February_5#Foo_in_fiction
pages = $heading
.next('ul')
.find('li')
.find('a:first-of-type')
.not('.external')
.map(function() { return mw.Title.newFromText($(this).text()); })
.get();
}
} else if ( config.xfd.type === 'rfd' || config.xfd.type === 'mfd' ) {
// For MFD, closed discussion are within a collapsed table
Line 530 ⟶ 851:
.children('a, span.plainlinks:not(.lx)')
.filter(':first-child')
.map(function() { return Pagemw.Title.newFromText($(this).text()); })
.get();
if ( config.xfd.type === 'rfd' ) {
var discussionTextdiscussionNodes = $heading
.nextUntil(config.xfd.html.head + ', div.xfd-closed, table.xfd-closed')
.textclone();
// Fix for "Comments in Local Time" gadget
discussionNodes.find('span.localcomments').each(function(){
var utcTime = $(this).attr('title');
$(this).text(utcTime);
});
var discussionText = discussionNodes.text();
// Ignore relisted discussions, and non-boxed closed discussions
if (
discussionText.includes('रीलिस्ट कइल गइलRelisted, देखींsee विकिपीडियाWikipedia:चर्चाRedirects खातिरfor अनुप्रेषणdiscussion') ||
discussionText.includes('चर्चाClosed बंद कइल गइलdiscussion, पूराsee चर्चाfull देखींdiscussion')
) {
return;
}
// Find first timestamp date
var firstdatePattfirstDatePatt = /(?:\d\d:\d\d, )(\d{1,2} \w+ \d{4})(?: \(UTC\))/;
var firstdateMatchfirstDateMatch = firstdatePattfirstDatePatt.exec(discussionText);
firstdatefirstDate = firstdateMatchfirstDateMatch && firstdateMatchfirstDateMatch[1];
}
} else {
Line 556 ⟶ 885:
.children('a')
.filter(':first-child')
.map(function() { return Pagemw.Title.newFromText($(this).text()); })
.get();
}
Line 565 ⟶ 894:
pages = false;
}
 
// Check discussion age (since last relist, if applicable)
// TODO: reduce redundancy with finding RfDs' first date
var isOld;
var $discussionNodes = $heading
.nextUntil(config.xfd.html.head + ', div.xfd-closed, table.xfd-closed')
.clone()
.find('span.localcomments')
.each(function(){
var utcTime = $(this).attr('title');
$(this).text(utcTime);
})
.end();
var lastRelist = $('<div>').append($discussionNodes).find('.xfd_relist').last().text();
if ( lastRelist ) {
$statusContainer.addClass('xfdc-relisted');
}
var notTranscludedCorrectlyPatt = /(?:Automated|Procedural) (?:comment|Note).*transcluded.*/i;
var notTranscludedCorrectlyMatch = $discussionNodes.text().match(notTranscludedCorrectlyPatt);
var notTranscludedCorrectlyComment = notTranscludedCorrectlyMatch && notTranscludedCorrectlyMatch[0];
 
var timestampPatt = /\d\d:\d\d, \d{1,2} \w+ \d{4} \(UTC\)/;
var listingTimestampMatch = lastRelist.match(timestampPatt) ||
notTranscludedCorrectlyComment && notTranscludedCorrectlyComment.match(timestampPatt) ||
$discussionNodes.text().match(timestampPatt);
var listingTimestampDate = listingTimestampMatch && dateFromSigTimestamp(listingTimestampMatch[0]);
if ( !listingTimestampDate ) {
$statusContainer.addClass('xfdc-unknownAge');
} else {
var millisecondsSinceListing = new Date() - listingTimestampDate;
var discussionRuntimeDays = 7;
var discussionRuntimeMilliseconds = discussionRuntimeDays * 24 * 60 * 60 * 1000;
isOld = millisecondsSinceListing > discussionRuntimeMilliseconds;
$statusContainer.addClass((isOld ? 'xfdc-old' : 'xfdc-notOld'));
}
 
// Create status span and notices div with unique id based on headingIndex
var uniqueID = 'XFDC' + headingIndex;
var $statusSpan = $('<span>')
$headlineSpan.after(
$('<span>')
.attr({'id':uniqueID, 'class':'xfdc-status'})
.text('[XFDcloser लोड होखत बाloading...]');
var $noticesDiv = $('<div>').attr({'id':uniqueID+'-notices', 'class':'xfdc-notices'});
);
if (config.isMobileSite) {
$heading.after(
$heading.next().prepend( $statusSpan, $noticesDiv );
$('<div>')
} else {
.attr({'id':uniqueID+'-notices', 'class':'xfdc-notices'})
$headlineSpan.after( $statusSpan );
);
$heading.after($noticesDiv);
}
// Create discussion object
return new Discussion(uniqueID, nompage, sectionHeader, editsection, pages, (firstdate || null));{
'id': uniqueID,
'nomPage': nompage,
'sectionHeader': sectionHeader,
'sectionNumber': editsection,
'pages': pages || [],
'firstDate': firstDate || null,
'isOld': !!isOld,
'isRelisted': !!lastRelist
});
};
// ---------- Discusssion prototype ------------------------------------------------------------- */
Line 590 ⟶ 964:
this.get$status().empty().append($status);
};
/**
// Open dialog
* Open dialog
*
* @param {Boolean} relisting open in relisting mode
* @returns {Boolean} Dialog was opened
*/
Discussion.prototype.openDialog = function(relisting) {
if (document.getElementById('xfdc-dialog')) {
// Another dialog is already open
return false;
}
this.dialog = new Dialog(this, !!relisting);
this.dialog.setup();
return true;
};
// Mark as finished
Line 602 ⟶ 986:
if ( aborted != null ) {
msg = [
$('<strong>').text( ( self.dialog && self.dialog.relisting ) ? 'रीलिस्टAborted छोड़ दिहल गइलrelist' : 'हटावल छोड़ दिहलAborted गइलclose' ),
( aborted === '' ) ? '' : ': ' + aborted
];
} else if ( self.dialog && self.dialog.relisting ) {
msg = [
'चर्चाDiscussion ',
$('<strong>').text('रीलिस्ट कइल गइलrelisted'),
' (reload page to see the actual relist)'
' (असली रीलिस्ट देखे खाती पन्ना रीलोड करीं)'
];
} else {
msg = [
'बंदClosed कइल गइलas ',
$('<strong>').text(self.taskManager.inputData.getResult()),
' (reload page to see the actual close)'
' (असल बंद कइल देखे खातिर पन्ना रीलोड करीं)'
];
}
Line 630 ⟶ 1,014:
};
// Get an array of page titles
Discussion.prototype.getPageTitles = function(pagearray, options) {
returnvar titles = (pagearray || this.pages).map(function(p) {
return p.getTitlegetPrefixedText();
});
if ( options && options.moduledocs ) {
return titles.map(function(t) {
var isModule = ( t.indexOf('Module:') === 0 );
return ( isModule ) ? t + '/doc' : t;
});
}
return titles;
};
// Get an array of page' talkpage titles (excluding pages which are themselves talkpages)
Discussion.prototype.getTalkTitles = function(pagearray) {
return (pagearray || this.pages).map(function(p) {
return p.getTalkgetTalkPage().getPrefixedText();
}).filter(function(t) { return t !== ''; });
};
// Get link text for a wikiink to the discussion - including anchor, except for AfDs/MfDs
Discussion.prototype.getNomPageLink = function() {
if (config.xfd.type === 'afd' || config.xfd.type === 'mfd') {
return this.nomPage;
} else {
return this.nomPage + '#' + mw.util.wikiUrlencode(this.sectionHeader).replace(/_/g, ' ');
}
};
Line 654 ⟶ 1,045:
};
// Get page object by matching the title
Discussion.prototype.getPageByTitle = function(ttitle, options) {
var convertModuleDoc = ( options && options.moduledocs && title.indexOf('Module:') === 0 );
var search = mw.Title.newFromText(decodeURIComponent(t)).getPrefixedText();
var titleToCheck = ( convertModuleDoc ) ? title.replace(/\/doc$/,'') : title;
 
var search = mw.Title.newFromText(titleToCheck).getPrefixedText();
for ( var i=0; i<this.pages.length; i++ ) {
if ( search === this.pages[i].getTitlegetPrefixedText() ) {
return this.pages[i];
}
Line 665 ⟶ 1,059:
// Get page object by matching the talkpage's title
Discussion.prototype.getPageByTalkTitle = function(t) {
var search = mw.Title.newFromText(decodeURIComponent(t)).getPrefixedText();
for ( var i=0; i<this.pages.length; i++ ) {
if ( search === this.pages[i].getTalkgetTalkPage().getPrefixedText() ) {
return this.pages[i];
}
Line 685 ⟶ 1,079:
'[',
$('<a>')
.attr('title', 'चर्चाClose समापनdiscussion...')
.text('समापन करींClose'),
']'
)
.click(function() {
return self.setStatusopenDialog('बंद) कइल&& जात बाself.setStatus('Closing...');
self.openDialog();
});
Line 700 ⟶ 1,093:
'[',
$('<a>')
.attr({title:'चर्चाRelist रीलिस्टdiscussion...', class:'XFDcloser-link-relist'})
.text('रीलिस्ट करींRelist'),
']'
)
.click(function() {
return self.openDialog(true) && self.setStatus('Relisting...');
self.setStatus('रीलिस्ट कइल जात बा...');
self.openDialog(true);
});
// quickKeep
var $qk = $('<a>')
.attr('title', 'quickKeep: close as "keep", remove nomination templates, '+
.attr('title', 'तुरंतरखल: "रखल जाय" के रूप में समापन, नामांकन टेम्पलेट हटाईं, '+
'add old xfd templates to talk pages')
'बातचीत पन्ना पर old xfd template जोड़ीं')
.text('तु•रखींqK')
.click(function(){
var inputData = new InputData(self);
inputData.result = 'रखल जायkeep';
inputData.after = 'doKeepActions';
self.setStatus('बंद कइल जात बाClosing...');
self.taskManager = new TaskManager(self, inputData);
self.taskManager.start();
Line 727 ⟶ 1,119:
var $qd = ( !config.user.isSysop && config.xfd.type !== 'tfd' ) ? '' : $('<a>')
.attr({
'title': 'quickDelete: close as "delete", delete nominated pages & their talk pages'+
'title': 'तुरंतहटावल: "हटावल जाय" के रूप में चर्चा बंद करीं, नामांकित पन्ना आ उनहन के बातचीत पन्ना हटाईं'+
(( config.xfd.type === 'rfd' ) ? '' :' & अनुप्रेषणredirects')+
(( config.xfd.type === 'afd' || config.xfd.type === 'ffd' ) ? ', बैकल्पिक रूप सेoptionally '+
'unlink backlinks' : ''),
'इहाँ आवे वाली कड़ी तूर दीं' : ''),
'class': 'xfdc-qd'
})
.text('तु•हटाqD');
if ( !config.user.isSysop && config.xfd.type == 'tfd' ) {
$qd.attr('title', 'quickDelete: close as "delete", tag nominated templates with '+
$qd.attr('title', 'तुरंतहटावल: "हटावल गइल" के रूप में चर्चा बंद करीं, नामांकित टेम्पलेट पर '+
'{{being deleted}}, add nominated templates to the holding cell as "orphan"')
'{{being deleted}} टैग लगाईं, नामांकित टेम्पलेट सभ के होल्डिंग सेल में "orphan" के रूप में जोड़ीं')
.click(function(){
var inputData = new InputData(self);
inputData.result = 'हटावल जायdelete';
inputData.after = 'holdingCell';
inputData.holdcell = 'orphan';
inputData.dontdeletetalk = true;
self.setStatus('बंद कइल जात बाClosing...');
self.taskManager = new TaskManager(self, inputData);
self.taskManager.start();
Line 749 ⟶ 1,142:
} else if ( config.user.isSysop ) {
$qd.click(function(){
$.when(config.xfd.type === 'tfd' ?
var inputData = new InputData(self);
multiButtonConfirm({
inputData.result = 'हटावल जाय';
title: 'Really delete?',
inputData.after = 'doDeleteActions';
message: 'Deletion will not remove transclusions from articles. Do you want to use the holding cell instead?',
inputData.deleteredir = ( config.xfd.type === 'rfd' ) ? null : true;
actions: [
inputData.unlinkbackl = ( config.xfd.type === 'afd' ||
{ label: 'Cancel', flags: 'safe' },
config.xfd.type === 'ffd' ) ? true : null;
{ label: 'Delete', flags: 'destructive', action: 'delete' },
 
{ label: 'Holding cell', flags: 'progressive', action: 'holdcell' }
self.setStatus('बंद कइल जात बा...');
],
self.taskManager = new TaskManager(self, inputData);
size: 'medium'
self.taskManager.start();
}) :
'delete'
)
.then(function(action) {
var inputData = new InputData(self);
inputData.result = 'delete';
if ( action === 'delete' ) {
inputData.after = 'doDeleteActions';
inputData.deleteredir = ( config.xfd.type === 'rfd' ) ? null : true;
inputData.unlinkbackl = ( config.xfd.type === 'afd' || config.xfd.type === 'ffd' ) ? true : null;
} else if ( action === 'holdcell' ) {
inputData.after = 'holdingCell';
inputData.holdcell = 'orphan';
inputData.dontdeletetalk = true;
} else {
// User selected Cancel
return;
}
self.setStatus('Closing...');
self.taskManager = new TaskManager(self, inputData);
self.taskManager.start();
});
});
}
Line 770 ⟶ 1,185:
$('<a>')
.attr('title', 'quickClose discussion...')
.text('तुरंत•समापनquickClose')
.click(function(){
$(this).hide().next().show();
Line 785 ⟶ 1,200:
'&nbsp;',
$('<span>')
.attr({title: 'कैंसिलCancel', class: 'xfdc-qc-cancel'})
.html("&nbsp;x&nbsp;")
.click(function(){
Line 798 ⟶ 1,213:
self.setStatus([
$close,
( self.pagesisBasicMode() || config.xfd.type=== false'cfd' ) ? '' : $quick,
( config.xfd.type==='cfd') ? '' : $relist,
additonal || ''
]);
Line 808 ⟶ 1,223:
// Preserve reference to discussion object
var self = this;
 
// If already in basic mode, just show links
if ( self.isBasicMode() ) {
self.showLinks();
return;
}
var pagesExistencesPromise = ( self.getPageTitles().length > 50 )
// Use Deferred objects to track when both queries are done, or either has failed
? $.Deferred().reject('Too many pages')
self.deferred.extraInfoExists = $.Deferred();
: API.get( {
self.deferred.extraInfoDates = $.Deferred();
action: 'query',
$.when(self.deferred.extraInfoExists, self.deferred.extraInfoDates)
titles: self.getPageTitles().join('|'),
.done( function() {
prop: 'info',
//Show links
inprop: 'talkid'
self.showLinks();
} )
.then(arrayFromResponsePages)
.fail( function(code, jqxhr) {
.then(function(pages) {
//Set basic mode
pages.forEach(function(page) {
self.pages = false;
var pageObject = self.getPageByTitle(page.title);
//Show basic-mode links
if ( !pageObject ) {
failDetails = $('<span>').addClass('xfdc-notice-error').append(
return $.Deferred().reject('Unexpacted title `'+page.title+'`');
'पन्ना जानकारी हासिल करे में खराबी (दोबारा कोसिस करे खातिर पन्ना रीलोड करीं) ',
}
$('<span>').addClass('xfdc-notice-error').append(
var pageExists = page.pageid > 0;
extraJs.makeErrorMsg(code, jqxhr)
var talkExists = page.talkid > 0;
)
setExistence(pageObject, pageExists);
);
setExistence(pageObject.getTalkPage(), talkExists);
self.showLinks(failDetails);
} );
return true;
});
// Check if pages and talk pages exist
apiCallback_getPagesInfo = function(result) {
var nominationDatePromise = ( config.xfd.type !== "afd" && config.xfd.type !== "mfd" )
if ( !result.query || !result.query.pageids ) {
? $.Deferred().resolve(self.nomPage.split(config.xfd.path)[1])
self.deferred.extraInfoExists.reject();
: API.get({
return;
}
var page_ids = result.query.pageids;
for (var i=0; i<page_ids.length; i++) {
title = result.query.pages[ page_ids[i] ].title;
var pageObject = self.getPageByTitle(title);
if ( !pageObject ) {
self.deferred.extraInfoExists.reject();
return;
}
pageObject.exists = page_ids[i] > 0;
pageObject.talkExists = result.query.pages[ page_ids[i] ].talkid > 0;
}
self.deferred.extraInfoExists.resolve();
};
// get page info from api
API.get( {
action: 'query',
titles: self.getPageTitles().join('|'),
prop: 'info',
inprop: 'talkid',
indexpageids: 1,
rawcontinue: ''
} )
.done( apiCallback_getPagesInfo )
.fail( function() {
self.deferred.extraInfoExists.reject();
} );
 
// Get nomination date:
if ( config.xfd.type !== "afd" && config.xfd.type !== "mfd" ) {
self.nomDate = self.nomPage.split(config.xfd.path)[1];
if ( config.xfd.type === "rfd" && self.firstDate === "" ) {
// For an RfD with no first comment date detected, use the nom page date in dmy format
self.firstDate = self.nomDate.replace(/(\d+) (\w*) (\d+)/g, "$3 $2 $1");
}
self.deferred.extraInfoDates.resolve();
} else {
//Api query to get nomination page content
apiCallback_getNomInfo = function(result) {
//get nomination date from when nom page was created
var p_id = result.query.pageids[0];
var timestamp = result.query.pages[p_id].revisions[0].timestamp;
var d = new Date(timestamp);
self.nomDate = d.getUTCDate().toString() + ' ' + config.mw.monthNames[d.getUTCMonth()] +
' ' + d.getUTCFullYear().toString();
self.deferred.extraInfoDates.resolve();
};
API.get( {
action: 'query',
titles: self.nomPage,
Line 894 ⟶ 1,255:
rvprop: 'timestamp',
rvdir: 'newer',
rvlimit: '1',
})
indexpageids: 1,
.then(pageFromResponse)
rawcontinue: ''
.then(function(page) {
} )
var revisionDate = new Date(page.revisions[0].timestamp);
.done( apiCallback_getNomInfo )
return dmyDateString(revisionDate);
.fail( function() {
});
self.deferred.extraInfoDates.reject();
} );
nominationDatePromise.then(function(nomDate) {
}
self.nomDate = nomDate;
// For an RfD with no first comment date detected, use the nom page date in dmy format
if ( config.xfd.type === "rfd" && !self.firstDate ) {
self.firstDate = nomDate.replace(/(\d+) (\w*) (\d+)/g, "$3 $2 $1");
}
});
return $.when(pagesExistencesPromise, nominationDatePromise).then(
function(){ return ''; },
function(failMessage, jqxhr) {
return $('<span>').addClass('xfdc-notice-error').append(
'Error retrieving page information (reload the page to try again) ',
$('<span>').addClass('xfdc-notice-error').append(
extraJs.makeErrorMsg(failMessage, jqxhr)
)
);
}
);
};
 
// Check if discussion is in 'basic' mode - i.e. no pages
Discussion.prototype.isBasicMode = function() {
return !this.pages || this.pages.length === 0;
};
 
Line 926 ⟶ 1,305:
this.interfaceWindow.setTitle( 'XFDcloser' );
this.interfaceWindow.setScriptName('(v' + config.script.version + ')');
this.interfaceWindow.addFooterLink('औजारscript मदद जानकारीdocumentation', 'WP:XFDC');
this.interfaceWindow.addFooterLink('फीडबैक देईंfeedback', 'प्रयोगकर्ता वार्ताWT:SM7/XFDC');
this.interfaceWindow.setContent(
$('<div>')
Line 938 ⟶ 1,317:
.get(0)
);
$(this.interfaceWindow.content).parent().parent().find('a.ui-dialog-titlebar-close.ui-corner-all').remove();
$('#xfdc-dialog').parent().css('background-color', '#f0f0f0');
};
 
// ---------- Rcat multiselect widget ----------------------------------------------------------- */
 
/**
* Dialog.RcatMultiselect
*
* Creates a modified OOUI MenuTagMultiselectWidget with Rcat templates as options,
* grouped as per https://en.wikipedia.org/wiki/Template:R_template_index
*
* @requires {Modules} oojs-ui-core, oojs-ui-widgets
* @param {function} onChangeCallback({String[]} datas)
* Callback function for when the selected rcats change, is passed an array of Strings
* each of which is a selected rcat template (including braces `{{` and `}}`). When all
* prior selections are removed, an empty array is passed.
* @param {object} context
* The context to be used as the `this` value when executing the callback function
* @param {jQuery} overlay
* Overlay element. If ommited, element with id `ejs-rcats-overlay` will be emptied and used
* if it exists, or else a div with that id will be created and used.
* @return {LookupMenuTagMultiselectWidget}
*/
Dialog.RcatMultiselect = function(onChangeCallback, context, overlay) {
 
// Extend OO.ui.MenuSelectWidget to use a more intuitive lookup system, such that
// e.g. typing "section" brings up `{{R to section}}` as a match
var LookupMenuSelectWidget = function(config) {
OO.ui.MenuSelectWidget.call(this, config);
};
LookupMenuSelectWidget.prototype = Object.create(OO.ui.MenuSelectWidget.prototype);
LookupMenuSelectWidget.prototype.getItemMatcher = function ( s, exact ) {
var re;
if ( s.normalize ) {
s = s.normalize();
}
s = exact ? s.trim() : s.replace( /^\s+/, '' );
re = s.replace( /([\\{}()|.?*+\-^$[\]])/g, '\\$1' ).replace( /\s+/g, '\\s+' );
if ( exact ) {
re = '^\\s*' + re + '\\s*$';
}
re = new RegExp( re, 'i' );
return function ( item ) {
var matchText = item.getMatchText();
if ( matchText.normalize ) {
matchText = matchText.normalize();
}
return re.test( matchText );
};
};
// Extend OO.ui.MenuTagMultiselectWidget to use a LookupMenuSelectWidget instead of
// the standard MenuSelectWidget
var LookupMenuTagMultiselectWidget = function ( config ) {
OO.ui.MenuTagMultiselectWidget.call(this, config);
// Override menu widget
this.menu = new LookupMenuSelectWidget( $.extend(
{
widget: this,
input: this.hasInput ? this.input : null,
$input: this.hasInput ? this.input.$input : null,
filterFromInput: !!this.hasInput,
$autoCloseIgnore: this.hasInput ?
this.input.$element : $( [] ),
$floatableContainer: this.hasInput && this.inputPosition === 'outline' ?
this.input.$element : this.$element,
$overlay: this.$overlay,
disabled: this.isDisabled()
},
config.menu
) );
this.menu.connect( this, {
choose: 'onMenuChoose',
toggle: 'onMenuToggle'
} );
if ( this.hasInput ) {
this.input.connect( this, { change: 'onInputChange' } );
}
if ( this.$input ) {
this.$input.prop( 'disabled', this.isDisabled() );
this.$input.attr( {
role: 'combobox',
'aria-owns': this.menu.getElementId(),
'aria-autocomplete': 'list'
} );
}
if ( !this.popup ) {
this.$content.append( this.$input );
this.$overlay.append( this.menu.$element );
}
//this.onMenuItemsChange();
};
LookupMenuTagMultiselectWidget.prototype = Object.create(OO.ui.MenuTagMultiselectWidget.prototype);
// Define new overlay, or use/reuse already defined element
if ( overlay == null ) {
if ( $('#ejs-rcats-overlay').length ) {
overlay = $('#ejs-rcats-overlay').first().empty();
} else {
overlay = $('<div>')
.attr('id', 'ejs-rcats-overlay')
.css({'z-index':'2000', 'position':'fixed', 'top':'0px', 'font-size':'85%'})
.prependTo('body');
}
}
// Make menu option widgets based on template name
var newRcatOption = function(val) {
return new OO.ui.MenuOptionWidget( {data: '{{'+val+'}}', label: '{{'+val+'}}'} );
};
// Make the widget
var rcatMultiselectWidget = new LookupMenuTagMultiselectWidget( {
allowArbitrary: true,
$overlay: overlay,
popup: false,
menu: {
items: [
// Common Rcats
new OO.ui.MenuSectionOptionWidget({label:'Common'}),
newRcatOption('R to related topic'),
newRcatOption('R from subtopic'),
newRcatOption('R to list entry'),
newRcatOption('R to section'),
new OO.ui.MenuSectionOptionWidget({label:'Related information'}),
newRcatOption('R from album'),
newRcatOption('R to article without mention'),
newRcatOption('R from book'),
newRcatOption('R to decade'),
newRcatOption('R from domain name'),
newRcatOption('R from top-level domain'),
newRcatOption('R from film'),
newRcatOption('R from gender'),
newRcatOption('R from list topic'),
newRcatOption('R from member'),
newRcatOption('R to related topic'),
newRcatOption('R from related word'),
newRcatOption('R from phrase'),
newRcatOption('R from school'),
newRcatOption('R from song'),
newRcatOption('R from subtopic'),
newRcatOption('R to subtopic'),
newRcatOption('R from Unicode'),
new OO.ui.MenuSectionOptionWidget({label:'Fiction'}),
newRcatOption('R from fictional character'),
newRcatOption('R from fictional element'),
newRcatOption('R from fictional location'),
newRcatOption('R to TV episode list entry'),
// Grammar, punctuation, and spelling
new OO.ui.MenuSectionOptionWidget({label:'Abbreviation'}),
newRcatOption('R to acronym'),
newRcatOption('R from acronym'),
newRcatOption('R to initialism'),
newRcatOption('R from initialism'),
new OO.ui.MenuSectionOptionWidget({label:'Capitalisation'}),
newRcatOption('R from CamelCase'),
newRcatOption('R from other capitalisation'),
newRcatOption('R from miscapitalisation'),
new OO.ui.MenuSectionOptionWidget({label:'Grammar & punctuation'}),
newRcatOption('R from modification'),
newRcatOption('R from plural'),
newRcatOption('R to plural'),
new OO.ui.MenuSectionOptionWidget({label:'Parts of speech'}),
newRcatOption('R from adjective'),
newRcatOption('R from adverb'),
newRcatOption('R from common noun'),
newRcatOption('R from gerund'),
newRcatOption('R from proper noun'),
newRcatOption('R from verb'),
new OO.ui.MenuSectionOptionWidget({label:'Spelling'}),
newRcatOption('R from alternative spelling'),
newRcatOption('R from ASCII-only'),
newRcatOption('R to ASCII-only'),
newRcatOption('R from diacritic'),
newRcatOption('R to diacritic'),
newRcatOption('R from misspelling'),
newRcatOption('R from stylization'),
// Alternative names
new OO.ui.MenuSectionOptionWidget({label:'Alternative names (general)'}),
newRcatOption('R from alternative language'),
newRcatOption('R from alternative name'),
newRcatOption('R from former name'),
newRcatOption('R from historic name'),
newRcatOption('R from incorrect name'),
newRcatOption('R from long name'),
newRcatOption('R from portmanteau'),
newRcatOption('R from short name'),
newRcatOption('R from sort name'),
newRcatOption('R from less specific name}'),
newRcatOption('R from more specific name'),
newRcatOption('R from synonym'),
newRcatOption('R from antonym'),
new OO.ui.MenuSectionOptionWidget({label:'Alternative names (people)'}),
newRcatOption('R from birth name'),
newRcatOption('R from given name'),
newRcatOption('R to joint biography'),
newRcatOption('R from married name'),
newRcatOption('R from name with title'),
newRcatOption('R from personal name'),
newRcatOption('R from pseudonym'),
newRcatOption('R from surname'),
new OO.ui.MenuSectionOptionWidget({label:'Alternative names (technical)'}),
newRcatOption('R from Java package name'),
newRcatOption('R from molecular formula'),
newRcatOption('R from technical name'),
newRcatOption('R to technical name'),
newRcatOption('R from trade name'),
new OO.ui.MenuSectionOptionWidget({label:'Alternative names (organisms)'}),
newRcatOption('R from scientific name'),
newRcatOption('R from alternative scientific name'),
newRcatOption('R to scientific name'),
new OO.ui.MenuSectionOptionWidget({label:'Alternative names (geography)'}),
newRcatOption('R from name and country'),
newRcatOption('R from more specific geographic name'),
newRcatOption('R from postal code'),
// Navigation aids
new OO.ui.MenuSectionOptionWidget({label:'Navigation'}),
newRcatOption('R to anchor'),
newRcatOption('R avoided double redirect'),
newRcatOption('R from file metadata link'),
newRcatOption('R to list entry'),
newRcatOption('R mentioned in hatnote'),
newRcatOption('R to section'),
newRcatOption('R from shortcut'),
newRcatOption('R from template shortcut'),
new OO.ui.MenuSectionOptionWidget({label:'Disambiguation'}),
newRcatOption('R from ambiguous term'),
newRcatOption('R to anthroponymy page'),
newRcatOption('R to disambiguation page'),
newRcatOption('R from incomplete disambiguation'),
newRcatOption('R from incorrect disambiguation'),
newRcatOption('R from other disambiguation'),
newRcatOption('R from unnecessary disambiguation'),
new OO.ui.MenuSectionOptionWidget({label:'Merge, duplicate & move'}),
newRcatOption('R from duplicated article'),
newRcatOption('R with history'),
newRcatOption('R from merge'),
newRcatOption('R from move'),
newRcatOption('R with old history'),
new OO.ui.MenuSectionOptionWidget({label:'To namespaces'}),
newRcatOption('R to category namespace'),
newRcatOption('R to draft namespace'),
newRcatOption('R to help namespace'),
newRcatOption('R to main namespace'),
newRcatOption('R to portal namespace'),
newRcatOption('R to project namespace'),
newRcatOption('R to talk page'),
newRcatOption('R to template namespace'),
newRcatOption('R to user namespace'),
// Miscellaneous
new OO.ui.MenuSectionOptionWidget({label:'ISO codes'}),
newRcatOption('R from ISO 4'),
newRcatOption('R from ISO 639 code'),
newRcatOption('R from ISO 3166 code'),
newRcatOption('R from ISO 4217 code'),
newRcatOption('R from ISO 15924 code'),
new OO.ui.MenuSectionOptionWidget({label:'Miscellaneous'}),
newRcatOption('R printworthy'),
newRcatOption('R unprintworthy'),
newRcatOption('Wikidata redirect')
]
}
} );
// Execute callback when selector data changes
rcatMultiselectWidget.on('change', function(selectedOptions) {
onChangeCallback.call(
context,
selectedOptions.map(function(optionWidget) {
return optionWidget.data;
})
);
});
return rcatMultiselectWidget;
};
 
Line 976 ⟶ 1,630:
 
// --- Make interface elements: ---
Dialog.prototype.makeHeader = function(multimode, isRelisting) {
var self = this;
Line 986 ⟶ 1,640:
.attr('id', 'closeXFD-interface-header-action')
.append(
( self.relisting ) ? 'चर्चाRelisting रीलिस्टdiscussion कइल जात बा' : 'चर्चा बंद कइल जातClosing बाdiscussion ',
$('<em>').text(self.discussion.sectionHeader),
' ',
Line 997 ⟶ 1,651:
.css({'background':'#ff8', 'padding':'1px'})
.text(
( self.discussion.isBasicMode() )|| ?( 'बेसिकconfig.xfd.type मोड=== '+cfd' && !self.relisting ) )
? 'basic mode only'
: self.discussion.pages.length +
( ( self.discussion.pages.length === 1 ) ? ' पन्नाpage' : ' पन्ना सभpages' )
),
( multimode ) ? '' : ' ',
( multimode ) ? '' : $('<a>').attr('id', 'closeXFD-pagecount-show').text('[देखींshow]'),
( multimode ) ? '' : $('<a>').attr('id', 'closeXFD-pagecount-hide').text('[छिपाईंhide]').hide()
)
)
Line 1,012 ⟶ 1,667:
// Multi/single-mode button
if ( !self.relisting && !self.discussion.pagesisBasicMode() && self.discussion.pages.length > 1 && config.xfd.type !== 'cfd' ) {
$header.prepend(
$('<button>')
.css('float', 'right')
.text(( multimode ) ? 'सिंगलSingle रिजल्टresult...' : 'कईMultiple रिजल्टresults...')
.click(function() {
if ( multimode ) {
Line 1,039 ⟶ 1,694:
.append(
$('<option>').attr('value', 'default').text(''),
$('<option>').attr('value', 'keep').text('रखल जायKeep'),
( config.xfd.type === 'ffd' ) ? '' : $('<option>')
.attr('value', 'redirect').text('अनुप्रेषणRedirect'),
( config.xfd.type === 'ffd' || config.xfd.type === 'rfd' ) ? '' : $('<option>')
.attr('value', 'बिलय कइल जायmerge').text('बिलयMerge'),
( config.xfd.type !== 'rfd' ) ? '' : $('<option>')
.attr('value', 'disambig').text('बहुअर्थी बनावल जायDisambiguate'),
$('<option>').attr('value', 'del').text('हटावल जायDelete'),
$('<option>').attr('value', 'na').text('(कौनोंno कार्रवाई नाaction)')
);
var $target = $('<span>')
Line 1,059 ⟶ 1,714:
// List of pages (or info on basic mode)
var isCfdClose = config.xfd.type === 'cfd' && !self.relisting;
var $pagesList = $('<ul>')
.attr('id', 'closeXFD-nominatedpages')
.css('font-size', '95%');
if ( !self.discussion.pagesisBasicMode() && !isCfdClose ) {
for ( var i=0; i<self.discussion.pages.length; i++ ) {
var pageTitle = self.discussion.pages[i].getTitlegetPrefixedText();
$('<li>')
.append(
Line 1,086 ⟶ 1,742:
$('<li>')
.append(
( !self.discussion.isBasicMode() && isCfdClose )
'नामांकित पन्ना ना मिलल। आप अभिन भी एह चर्चा के ',
? 'Automated post-close actions are not available for CFDs.'
( self.relisting ) ? 'रीलिस्ट' : 'बंद',
: 'Nominated pages were not detected.',
' क सकत बानी ',
'You can still ',
( self.relisting ) ? 'relist' : 'close',
' this ',
config.xfd.type.toUpperCase(),
' discussion, but updating the nomination templates will need to be done manually '+
' चर्चा बा, लेकिन नामांकन टेम्पलेट के मैनुअली अपडेट करे के पड़ी '+
'&ndash; देखींsee ',
extraJs.makeLink('WP:'+config.xfd.type.toUpperCase()+'AI'),
' for instructions.'
' पर निर्देस दिहल बा।'
)
.appendTo($pagesList);
Line 1,107 ⟶ 1,766:
var t = $li.find('.closeXFD-pagelist-title').text();
self.inputData.pageActions[t].action = v;
if ( v === 'redirect' || v === 'बिलय कइल जायmerge' ) {
$li.find('.closeXFD-pagelist-target').show();
} else {
Line 1,116 ⟶ 1,775:
$pagesList.find('input').change(function(){
var t = $(this).parent().parent().find('.closeXFD-pagelist-title').text();
self.inputData.pageActions[t].target = Pagemw.Title.newFromText(
$(this).val().trim()
);
Line 1,132 ⟶ 1,791:
$('<em>')
.append(
'See the ',
'सलाह खातिर उचित आ अनुचित समापन के बारे में ',
extraJs.makeLink('WP:NACD'),
' guideline for advice on appropriate and inappropriate closures'
' निर्देस देखीं'
),
$('<hr>')
Line 1,144 ⟶ 1,803:
var self = this;
var $resultContainer = $('<div>')
.attr('id', 'closeXFD-resultContainer')
.css({'float':'left', 'width':'99%', 'padding-bottom':'1%'})
.append(
$('<div>').append(
$('<strong>').text('रिजल्टResult'),
// Speedy
$('<span>').addClass('xfdc-dialog-bracketedOption').append(
Line 1,157 ⟶ 1,816:
self.inputData.speedy = ( $(this).prop('checked') );
}),
$('<label>').attr('for', 'closeXFD-speedy').text('तुरंतSpeedy')
)
),
Line 1,164 ⟶ 1,823:
$('<span>').attr('class', 'xfdc-dialog-option').append(
$('<input>').attr({'type':'radio', 'name':'closeXFD-result',
'class':'closeXFD-keepResult', 'id':'closeXFD-result-keep', 'value':'रखल जायkeep'}),
$('<label>').attr('for', 'closeXFD-result-keep').text('रखल जायKeep')
),
// Redirect
Line 1,175 ⟶ 1,834:
$('<label>')
.attr('for', 'closeXFD-result-redir')
.text(( config.xfd.type === 'rfd' ) ? 'टारगेट बदलींRetarget' : 'अनुप्रेषण करींRedirect'),
( !config.user.isSysop ) ? '' : $('<label>')
.attr('for', 'closeXFD-result-redir')
.text(( config.xfd.type === 'rfd' ) ? 'हटाईंDelete and टारगेट बदलींretarget' : 'हटाईं आDelete अनुप्रेषणand करींredirect')
.hide()
),
Line 1,187 ⟶ 1,846:
'class':'closeXFD-keepResult', 'id':'closeXFD-result-softredir',
'value':'soft redirect'}),
$('<label>').attr('for', 'closeXFD-result-softredir').text('सॉफ्टSoft अनुप्रेषणredirect'),
( !config.user.isSysop ) ? '' : $('<label>')
.attr('for', 'closeXFD-result-softredir').text('हटाईंDelete and सॉफ्टsoft अनुप्रेषणredirect').hide()
),
// No consensus
Line 1,195 ⟶ 1,854:
$('<input>').attr({'type':'radio', 'name':'closeXFD-result',
'class':'closeXFD-keepResult', 'id':'closeXFD-result-nocon',
'value':'आमno सहमती नइखेconsensus'}),
$('<label>').attr('for', 'closeXFD-result-nocon').text('आमNo सहमती नइखेconsensus')
),
// Merge
Line 1,202 ⟶ 1,861:
.attr('class', 'xfdc-dialog-option').append(
$('<input>').attr({'type':'radio', 'name':'closeXFD-result',
'id':'closeXFD-result-merge', 'value':'बिलय कइल जायmerge'}),
$('<label>').attr('for', 'closeXFD-result-merge').text('बिलय कइल जायMerge')
),
// Disambiguate
Line 1,210 ⟶ 1,869:
$('<input>').attr({'type':'radio', 'name':'closeXFD-result',
'id':'closeXFD-result-disambig', 'value':'disambiguate'}),
$('<label>').attr('for', 'closeXFD-result-disambig').text('बहुअर्थी बनावल जायDisambiguate')
),
// Delete
Line 1,216 ⟶ 1,875:
.attr('class', 'xfdc-dialog-option').append(
$('<input>').attr({'type':'radio', 'name':'closeXFD-result',
'class':'closeXFD-deleteResult', 'id':'closeXFD-result-delete', 'value':'हटावल जायdelete'}),
$('<label>').attr('for', 'closeXFD-result-delete').text('हटावल जायDelete')
),
// Delete (disabled)
Line 1,225 ⟶ 1,884:
'class':'closeXFD-deleteResult', 'id':'closeXFD-result-delete-disabled',
'disabled':'disabled'}),
extraJs.addTooltip(
$('<label>').attr('for', 'closeXFD-result-delete-disabled').append(
$('<label>')
'हटावल जाय ',
.attr('for', 'closeXFD-result-delete-disabled')
extraJs.makeTooltip('गैर-प्रबंधक द्वारा समापन उचित नइखे अगर रिजल्ट '+
.text('Delete '),
'एह चर्चा के प्रबंधक द्वारा समापन करे के जरूरत बा (देखीं [[WP:BADNAC]])')
'Non-admin closure is not appropriate when the result will require action by an administrator (per [[WP:BADNAC]])'
)
),
Line 1,236 ⟶ 1,896:
$('<input>').attr({'type':'radio', 'name':'closeXFD-result',
'class':'closeXFD-deleteResult', 'id':'closeXFD-result-softdel',
'value':'सॉफ्टsoft डिलीटdelete'}),
$('<label>').attr('for', 'closeXFD-result-softdel').text('सॉफ्टSoft डिलीटdelete')
),
// Custom
Line 1,243 ⟶ 1,903:
$('<input>').attr({'type':'radio', 'name':'closeXFD-result',
'id':'closeXFD-result-custom', 'value':'custom'}),
$('<label>').attr('for', 'closeXFD-result-custom').text('अपने अनुसारCustom')
)
),
Line 1,250 ⟶ 1,910:
.css({'clear':'both', 'padding-bottom':'1%', 'display':'none'})
.append(
$('<label>').attr('for', 'closeXFD-result-custom-input').text('अपनेCustom अनुसार रिजल्टresult: '),
$('<input>')
.attr({'type':'text', 'name':'closeXFD-result-custom-input',
Line 1,264 ⟶ 1,924:
.append(
$('<label>').attr({'id':'closeXFD-result-target-label', 'for':'closeXFD-result-target'})
.text('टारगेटTarget:'),
$('<input>')
.attr({'type':'text', 'name':'closeXFD-result-target', 'id':'closeXFD-result-target'})
.change(function(){
self.inputData.target = Pagemw.Title.newFromText(
$('#closeXFD-result-target').val().trim()
);
Line 1,285 ⟶ 1,945:
default:
case 'keep':
case 'आमno सहमती नइखेconsensus':
$('.closeXFD-keepOptions').show();
$('.closeXFD-redirectOptions, .closeXFD-mergeOptions, .closeXFD-disambigOptions, .closeXFD-deleteOptions, '+
Line 1,304 ⟶ 1,964:
$('.closeXFD-keepOptions, .closeXFD-mergeOptions, .closeXFD-disambigOptions, .closeXFD-deleteOptions, '+
'#closeXFD-customOptions, #closeXFD-resultContainer-custom').hide();
$('#closeXFD-result-target-label').text(extraJs.toSentenceCase(v) + ' टारगेटto: ');
// default options:
if (
Line 1,310 ⟶ 1,970:
( currentAfter !== 'doRedirectActions' && currentAfter !== 'noAction' )
) {
$('#closeXFD-after-doRedirectActions, #closeXFD-redir-addRcats-on')
.prop('checked', true).change();
}
break;
case 'बिलय कइल जायmerge':
$('.closeXFD-mergeOptions, #closeXFD-resultContainer-target').show();
$('.closeXFD-keepOptions, .closeXFD-redirectOptions, .closeXFD-disambigOptions, .closeXFD-deleteOptions, '+
'#closeXFD-customOptions, #closeXFD-resultContainer-custom').hide();
$('#closeXFD-result-target-label').text('मेंMerge बिलयto: ');
// default options:
if (
Line 1,340 ⟶ 2,000:
}
break;
case 'हटावल जायdelete':
case 'soft delete':
$('.closeXFD-deleteOptions').show();
Line 1,354 ⟶ 2,014:
) {
$('#closeXFD-after-' +
(( config.userxfd.isSysoptype === 'tfd' ) ? 'doDeleteActionsholdingCell' : 'holdingCelldoDeleteActions' ) +
', #closeXFD-del-deleteredir, #closeXFD-del-unlinkbackl')
.prop('checked', true).change();
Line 1,391 ⟶ 2,051:
.append(
$('<strong>').attr('id', 'closeXFD-rationale-label')
.text( ( self.relisting ) ? 'रीलिस्टRelist कमेन्टcomment' : (( multimode ) ? 'कारणRationale' : 'अउरी अन्यAdditional '+
'कारणrationale')),
( !multimode ) ? ' (बैकल्पिकoptional):' : $('<a>')
.addClass('xfdc-dialog-bracketedOption')
.text('copy from above')
Line 1,402 ⟶ 2,062:
if ( a ) {
a = a
.replace('del', 'हटावल जायdelete')
.replace(/(default|na)/, ' ');
} else {
a = ' ';
}
var t = ( /(बिलय कइल जायmerge|redirect)/.test(a) ) ? ' टारगेटto [[' +
self.inputData.pageActions[p].target + ']] पर\n' : '\n';
results += "*'''" + extraJs.toSentenceCase(a) + "''' [[" + p + "]]" + t;
}
Line 1,436 ⟶ 2,096:
.change(),
$('<label>').attr('for', 'closeXFD-rationale-sentence')
.text('कारणRationale नयाis वाक्यnot नइखेa new sentence')
)
);
Line 1,444 ⟶ 2,104:
.css({'clear':'both', 'padding-bottom':'1%'})
.append(
extraJs.addTooltip(
$('<label>').attr('for', 'closeXFD-resultSummary-input').append(
$('<label>').attr('for', 'closeXFD-resultSummary-input').text('Result summary: '),
'रिजल्ट के सारांश',
extraJs.makeTooltip('Appears in bold text before the rationale; also used in edit summaries, and in'+
'edit summaries, and in Old ' + config.xfd.type + ' templates'),
': '
),
$('<input>')
.attr({
'type':'text',
'name':'closeXFD-resultSummary-input',
'id':'closeXFD-resultSummary-input'})
})
.css({"margin-left": "0.5em"})
.change(function(){
self.inputData.result = $(this).val().trim();
Line 1,471 ⟶ 2,134:
.css('max-width', ( multimode ) ? '30%' : '40%')
.append(
$('<strong>').text('बंदAfter करे के बादclosing:').css('display','block'),
// KeepActions
$('<div>')
Line 1,478 ⟶ 2,141:
.append(
( multimode ) ? $('<strong>')
.text('"रखल जायKeep" पन्नाpages: ') : $('<input>')
.attr({
'type':'radio',
Line 1,485 ⟶ 2,148:
'value':'doKeepActions'
}),
extraJs.addTooltip(
$(( multimode ) ? '<span>' : '<label>')
$(( multimode ) ? '<span>' : '<label>')
.attr('for', 'closeXFD-after-doKeepActions')
.attr('for', 'closeXFD-after-doKeepActions')
.append(
.text('Update pages and talk pages '),
'पन्ना आ बातचीत पन्ना अपडेट करीं ',
'Remove nomination templates, and add old xfd templates to talk pages'
extraJs.makeTooltip('नामांकन टेम्पलेट हटाईं, आ old xfd टेम्पलेट जोड़ीं '+
'to talk pages')
)
),
Line 1,499 ⟶ 2,161:
.append(
( multimode ) ? $('<strong>')
.text('"अनुप्रेषण कइल जायRedirect" पन्नाpages: ') : $('<input>').attr({
'type':'radio',
'name':'closeXFD-after',
Line 1,505 ⟶ 2,167:
'value': 'doRedirectActions'
}),
extraJs.addTooltip(
$(( multimode ) ? '<span>' : '<label>')
$(( multimode ) ? '<span>' : '<label>')
.attr('for', 'closeXFD-after-doRedirectActions')
.attr('for', 'closeXFD-after-doRedirectActions')
.append(
.text('Redirect pages and update talk pages '),
'पन्ना अनुप्रेषित करीं आ वार्ता पन्ना अपडेट करीं ',
'Redirect nominated pages to the specified target, '+
extraJs.makeTooltip('बतावल टारगेट पर पन्ना अनुप्रेषित करीं, '+
'and add old xfd templates to talk pages'
'आ वार्ता पन्ना पर old xfd template जोड़ीं')
)
),
Line 1,519 ⟶ 2,181:
.append(
( multimode ) ? $('<strong>')
.text('"बिलय कइल जायMerge" पन्नाpages: ') : $('<input>').attr({
'type':'radio',
'name':'closeXFD-after',
Line 1,525 ⟶ 2,187:
'value': 'doMergeActions'
}),
extraJs.addTooltip(
$(( multimode ) ? '<span>' : '<label>')
$(( multimode ) ? '<span>' : '<label>')
.attr('for', 'closeXFD-after-doMergeActions')
.attr('for', 'closeXFD-after-doMergeActions')
.append(
.text('Update pages and talk pages '),
extraJs.makeTooltip('Replace nomination templates with merge templates, '+
'and add old xfd templates to talk pages')
)
),
Line 1,539 ⟶ 2,201:
.append(
( multimode ) ? $('<strong>')
.text('"बहुअर्थी बनावल जायDisambiguate" पन्नाpages: ') : $('<input>')
.attr({
'type':'radio',
Line 1,546 ⟶ 2,208:
'value':'doDisambigActions'
}),
extraJs.addTooltip(
$(( multimode ) ? '<span>' : '<label>')
$(( multimode ) ? '<span>' : '<label>')
.attr('for', 'closeXFD-after-doDisambigActions')
.attr('for', 'closeXFD-after-doDisambigActions')
.append(
.text('Update pages and talk pages '),
'पन्ना आ वार्ता पन्ना अपडेट करीं ',
'Remove nomination templates, and add old xfd templates '+
extraJs.makeTooltip('नामांकन टेम्पलेट हटाईं, आ old xfd टेम्पलेट जोड़ीं '+
'to talk pages')
)
),
Line 1,565 ⟶ 2,227:
'value': 'doDeleteActions'
}),
extraJs.addTooltip(
$('<label>').attr('for', 'closeXFD-after-doDeleteActions').append(
$('<label>')
'पन्ना हटाईं ',
.attr('for', 'closeXFD-after-doDeleteActions')
extraJs.makeTooltip('नामांकित पन्ना हटाईं (अगर अलग से न बतावल होखे) '+
.text('Delete pages '),
'उनहन के वार्तो पन्ना हटाईं')
'Delete nominated pages and (unless otherwise specified) '+
'their talk pages'
)
),
Line 1,582 ⟶ 2,246:
'value':'holdingCell'
}),
extraJs.addTooltip(
$('<label>').attr('for', 'closeXFD-after-holdingCell').append(
$('<label>')
'List pages at holding cell ',
.attr('for', 'closeXFD-after-holdingCell')
extraJs.makeTooltip('Replace nomination template with {{Being deleted}}, '+
.text('andList listpages at the specified holding cell section'),
'Replace nomination template with {{Being deleted}}, '+
'and list at the specified holding cell section'
)
),
Line 1,593 ⟶ 2,259:
.hide()
.append(
$('<strong>').text('"हटावल जायDelete" पन्नाpages: '),
( !config.user.isSysop ) ? '' : extraJs.addTooltip(
$('<span>').append(
$("<span>").text('Delete pages '),
( !config.user.isSysop ) ? '' : 'पन्ना हटाईं ',
'Delete nominated pages and (unless otherwise specified) their talk pages'
( !config.user.isSysop ) ? '' : extraJs.makeTooltip('Delete nominated pages and '+
),
'(unless otherwise specified) their talk pages'),
( config.xfd.type !== 'tfd' ) ? '' : ((|| !config.user.isSysop ) ? '' or: l' :or 'L'), +
( config.xfd.type !== 'tfd' ) ? '' : extraJs.addTooltip(
'ist pages at holding cell ',
$("<span>").text( (( config.xfduser.type !== 'tfd'isSysop ) ? 'l' : extraJs.makeTooltip('ReplaceL') nomination+ '+ist pages at holding cell' ),
'Replace nomination template with {{Being deleted}}, and list at the specified holding cell section'+
'holding cell section')
)
),
Line 1,618 ⟶ 2,283:
}),
$(( multimode ) ? '<span>' : '<label>')
.attr('for', 'closeXFD-after-noAction').text('कौनोंNo ऑटोमेटिकautomated कार्रवाई नाactions')
)
)
Line 1,661 ⟶ 2,326:
.hide()
.append(
$('<strong>').text(( multimode ) ? 'अनुप्रेषणRedirect बिकल्पoptions' : 'बिकल्पOptions')
.css('display','block'),
// Delete before redirecting
Line 1,680 ⟶ 2,345:
}),
$('<label>').attr('for', 'closeXFD-redir-deleteFirst')
.text('Delete before redirecting')
.text('अनुप्रेषण बनावे से पहिले हटाईं')
),
// Rcats
$('<div>').append(
$('<input>').attr({
'type':'radiocheckbox',
'name':'closeXFD-redir-addRcats',
'id': 'closeXFD-redir-addRcats-onrcats', 'value':'on'}).prop('checked', true),
'disabled': true
}).prop('checked', ( config.xfd.type === 'afd' )),
$('<label>').attr('for', 'closeXFD-redir-rcats').append(
extraJs.addTooltip(
$('<a>')
$('<a>')
.attr({
'href':'https://bhen.wikipedia.org/wiki/Template:R_template_index',
'target':'_blank'
})
.text('Rcats: '),
'Full markup required, e.g. "{{R to section}}". '+
": ",
extraJs.makeTooltip('Full markup required, e.g. "{{R to section}}";. '+
'Multiple rcats can be specified, e.g. "{{R from book}}'+
'{{R to anchor}}". Leave blank if unsure which rcat to use.')
)
),
self.rcatSelector.$element.detach()
),
// No Rcats
$('<div>').append(
$('<input>').attr({'type':'radio', 'name':'closeXFD-redir-addRcats',
'id':'closeXFD-redir-addRcats-off', 'value':'off'}),
$('<label>').attr('for', 'closeXFD-redirectOption-rcats-off').append(
"Do not add rcats ",
extraJs.makeTooltip('ज्यादातर अनुप्रेषण सभ के उचित अनुप्रेषण श्रेणी में रखल जाला। एकरा के तब्बे इस्तेमाल करीं '+
' जब आपके निश्चित होखे कि कौनों उचित अनुप्रेषण श्रेणी ना बाटे')
)
)
),
.find("input[type=radio][name='closeXFD-redir-addRcats']").change(function(){
if ( $(this).val() === 'on' ) {
self.rcatSelector.setDisabled(false);
self.storeRcatData(self.rcatSelector.getItemsData());
} else {
self.rcatSelector.setDisabled(true);
self.inputData.rcats = false;
}
})
.end(),
// Merge options:
Line 1,795 ⟶ 2,448:
'checked':'checked'}),
$('<label>').attr('for', 'closeXFD-del-deleteredir')
.text('अनुप्रेषणAlso सभdelete भी हटा दींredirects')
),
// Unlink backlinks
Line 1,803 ⟶ 2,456:
'id':'closeXFD-del-unlinkbackl', 'value':'unlinkbackl',
'checked':'checked'}),
$('<label>').attr('for', 'closeXFD-del-unlinkbackl').text('कड़ीUnlink तूर दींbacklinks')
),
// Delete and redirect
Line 1,812 ⟶ 2,465:
// Shortcut for switching to 'Redirect' and selects 'Delete before redirecting'
$('<a>').attr('id', 'closeXFD-del-deleteAndRedir')
.text('हटाएँDelete and अनुप्रेषण बनाईंredirect...')
.click(function(){
$('#closeXFD-result-redir').prop('checked', true).change();
Line 1,927 ⟶ 2,580:
$('<button>')
.attr('id', 'closeXFD-interface-cancel')
.text('कैंसिलCancel')
.click(function() {
self.close();
Line 1,937 ⟶ 2,590:
$('<button>')
.attr('id', 'closeXFD-interface-closedisc')
.text('चर्चाClose बंद करींDiscussion')
.click(function() {
if ( multimode ) {
Line 1,947 ⟶ 2,600:
$('<button>')
.attr('id', 'closeXFD-interface-preview')
.text('झलक देखींPreview')
.click(function() {
if ( multimode ) {
Line 1,958 ⟶ 2,611:
} else {
$buttons.prepend(
$('<button>').attr('id', 'closeXFD-interface-relistdisc').text('चर्चाRelist रीलिस्ट करींDiscussion')
.click(function() {
self.close();
Line 1,964 ⟶ 2,617:
self.discussion.taskManager.start();
}),
$('<button>').attr('id', 'closeXFD-interface-previewRelist').text('झलकPreview')
.click(function() {
self.showPreview(true);
Line 1,981 ⟶ 2,634:
$('.closeXFD-keepOptions').toggle(this.inputData.inPageActions('keep'));
$('.closeXFD-redirectOptions').toggle(this.inputData.inPageActions('redirect'));
$('.closeXFD-mergeOptions').toggle(this.inputData.inPageActions('बिलय कइल जायmerge'));
$('.closeXFD-disambigOptions').toggle(this.inputData.inPageActions('disambig'));
$('.closeXFD-deleteOptions').toggle(this.inputData.inPageActions('del'));
Line 1,990 ⟶ 2,643:
Dialog.prototype.storeRcatData = function(rcatData) {
this.inputData.rcats = rcatData.join('\n').trim();
$('#closeXFD-redir-rcats').prop('checked', rcatData.length > 0);
};
 
Line 1,998 ⟶ 2,652:
this.emptyContent();
if ( config.xfd.type !== 'ffd' && config.xfd.type !== 'cfd' && !self.discussion.isBasicMode() ) {
this.rcatSelector = extraJsDialog.makeRcatCapsuleMultiselectRcatMultiselect(self.storeRcatData, self);
}
this.inputData = new InputData(this.discussion);
this.addToHeader(this.makeHeader(false, this.relisting));
this.addToBody(this.makePagesList());
Line 2,015 ⟶ 2,669:
this.addToBody(this.makeCloseResult());
this.addToBody(this.makeRationaleBox());
if ( config.xfd.type === 'cfd' || this.discussion.isBasicMode() ) {
this.inputData.after = 'noAction';
} else {
if ( config.xfd.type === 'afd' ) {
this.rcatSelector.setItemsFromDatasetValue(['{{R to related topic}}']);
}
this.addToBody(this.makeAfterActions());
Line 2,040 ⟶ 2,694:
if ( config.xfd.type !== 'ffd' && !self.discussion.isBasicMode() ) {
this.rcatSelector = extraJsDialog.makeRcatCapsuleMultiselectRcatMultiselect(self.storeRcatData, self);
}
Line 2,056 ⟶ 2,710:
this.addToBody(this.makeAfterActions(true));
if ( config.xfd.type === 'afd' ) {
this.rcatSelector.setItemsFromDatasetValue(['{{R to related topic}}']);
}
this.addToBody(this.makeOptions(true));
Line 2,075 ⟶ 2,729:
preview_wikitext = '{{Relist|1=' + this.inputData.getRelistComment() + '}}';
} else {
preview_wikitext = "एहThe चर्चाresult केरिजल्टof रहलthe discussion was '''" +
this.inputData.getResult()+
"'''" +
(( this.inputData.getTargetLink() ) ? ' टारगेटto ' + this.inputData.getTargetLink() : '') +
( (this.inputData.getRationale()) || '.' ) +
' ' +
config.user.sig;
Line 2,090 ⟶ 2,744:
})
.done(function(result) {
var preview_html = result.parse.text['*'];
$('#closeXFD-preview-output').html(preview_html).show().find('a').attr('target', '_blank');
})
Line 2,100 ⟶ 2,754:
.css('color', '#f00')
.append(
'Error: Preview failed. ',
formatApiError(code, jqxhr)
$('<br>'),
'Details: ',
extraJs.makeErrorMsg(code, jqxhr)
)
)
Line 2,133 ⟶ 2,785:
// Evaluate standard close
Dialog.prototype.evaluateClose = function(preview) {
var self = this;
var errors = [];
Line 2,148 ⟶ 2,800:
case 'redirect':
case 'soft redirect':
case 'बिलय कइल जायmerge':
if ( $('#closeXFD-result-target').val().trim() === '' ) {
// Target not specified
Line 2,155 ⟶ 2,807:
if ( !self.inputData.target ) {
// Invalid target
window.alert('Bad ' + self.inputData.result +
' target: the title is invalid.');
errors.push('#closeXFD-resultContainer-target');
Line 2,223 ⟶ 2,875:
// Evaluate multimode close
Dialog.prototype.evaluateMultimodeClose = function(preview) {
var self = this;
var errors = [];
 
Line 2,251 ⟶ 2,903:
} else if (
self.inputData.pageActions[p] === 'redirect' ||
self.inputData.pageActions[p] === 'बिलय कइल जायmerge'
) {
// Check target specified
Line 2,258 ⟶ 2,910:
errors.push('#'+targetInputId);
} else if ( !self.inputData.pageActions[p].target ) {
window.alert('Bad ' + self.inputData.pageActions[p].action + 'target for ' +
p +' – the title is invalid.');
errors.push('#'+targetInputId);
Line 2,268 ⟶ 2,920:
if (
config.xfd.type === 'tfd' &&
self.inputData.inPageActions('बिलय कइल जायmerge') &&
!self.inputData.mergeHoldcell
) {
Line 2,381 ⟶ 3,033:
var output = '';
if ( this.speedy ) {
output += 'तुरंतspeedy ';
}
if (
Line 2,387 ⟶ 3,039:
/(?:retarget|redirect|soft redirect)/.test(this.result)
) {
output += 'हटावलdelete जाय आand ';
}
output += ( this.result === 'custom') ? this.customResult : this.result;
Line 2,398 ⟶ 3,050:
if ( this.multimode && p ) {
return this.pageActions[p].target.getPrefixedText();
} else if ( /(?:retarget|redirect|soft redirect|बिलय कइल जायmerge)/.test(this.result) ) {
return this.target && this.target.getPrefixedText();
} else {
Line 2,429 ⟶ 3,081:
if ( self.multimode ) {
for ( var p in self.pageActions ) {
if ( self.pageActions[p] && /(redirect|बिलय कइल जायmerge)/.test(self.pageActions[p].action) ) {
output.push(self.pageActions[p].target);
}
Line 2,446 ⟶ 3,098:
if (
self.pageActions[p] &&
self.pageActions[p].action === 'बिलय कइल जायmerge' &&
self.pageActions[p].target.getPrefixedText() === target
) {
Line 2,505 ⟶ 3,157:
var multimode = self.inputData.multimode;
var warnings = [];
 
// Check if closing dicussion early (and it hasn't been relisted )
if ( !self.discussion.isOld && !self.discussion.isRelisted ) {
warnings.push('It has not yet been 7 days since the discussion was listed.');
}
// Check for mass actions when closing:
Line 2,529 ⟶ 3,186:
if ( targetObjectsArray ) {
$.each(targetObjectsArray, function(_i, t) {
if ( t && !t.hasCorrectNamespace(t)) {
warnings.push( 'Target page [["' + t.getPrefixedText() + '"]] is not in the ' +
config.mw.namespaces[(config.xfd.ns_number[0]).toString()] + ' namespace.');
}
});
Line 2,537 ⟶ 3,194:
//Check namespaces of nominated pages
var wrongNamespacePages = !self.discussion.pagesisBasicMode() && self.discussion.pages.filter(function(p) {
return !p.hasCorrectNamespace(p);
});
if ( wrongNamespacePages.length > 0 ) {
warnings.push(
'The following pages are not in the ' +
config.mw.namespaces[(config.xfd.ns_number[0]).toString()] +
' namespace:<ul><li>[[' +
wrongNamespacePages.map(function(p){ return p.getTitlegetPrefixedText(); }).join(']]</li><li>[[') +
']]</li>'
);
Line 2,557 ⟶ 3,214:
};
 
// Resolve redirects:
// If nominated pages are redirects (at venues other than RfD), the script can't know if this was
// appropriate, where results such as 'Delete' should be applied to the target, or an out-of-process
// redirection, where results such as 'Delete' should be applied to the redirect
/**ResolveRedirects
TaskManager.prototype.resolveRedirects = function(callback) {
* @returns {Promise<Boolean>} `true` when completed and okay to continue; rejected if aborted by user
*/
TaskManager.prototype.resolveRedirects = function() {
var self = this;
Line 2,571 ⟶ 3,230:
config.xfd.type === 'rfd' ||
// Basic mode (no pages detected)
!self.discussion.pagesisBasicMode() ||
// Relisting for other than FfD/TfD
( relisting && !/(ffd|tfd)/.test(config.xfd.type) ) ||
Line 2,580 ⟶ 3,239:
) {
// Nominate pages expected to be redirects, no need to resolve them
return $.Deferred().resolve(true).promise();
callback.call(self);
return;
}
return API.get( {
var processPages = function(result) {
action: 'query',
titles: self.discussion.getPageTitles().join('|'),
redirects: 1,
prop: 'info',
inprop: 'talkid'
} )
.then( function(result) {
if ( result.query && result.query.redirects ) {
var redirections = result.query.redirects.map(function(redirect) {
// Redirects are present, need to ask user what to do
return '<li>[[' + redirect.from + ']] → [[' + redirect.to + ']]</li>';
});
 
var redirects_msg = "The following nominated pages are redirects to other pages:<ul>" +
var redir_from = new Array(result.query.redirects.length);
redirections.join("") + "</ul>";
var redir_to = new Array(result.query.redirects.length);
var redir_list = new Array(result.query.redirects.length);
return multiButtonConfirm({
for (var i=0; i<result.query.redirects.length; i++) {
redir_from[i]title: ='Use result.query.redirects[i].from; or targets?',
message: redirects_msg,
redir_to[i] = result.query.redirects[i].to;
actions: [
redir_list[i] = '[[' + redir_from[i] + ']] → [[' + redir_to[i] + ']]';
{ label: 'Cancel', flags: 'safe' },
}
{ label: 'Use redirects', action: 'reject' },
var redirects_msg = "The following nominated pages are redirects to other pages:<ul><li>" +
{ label: 'Use targets', action: 'accept', flags: 'progressive' }
redir_list.join("</li><li>") + "</li></ul>";
],
size: 'medium'
// Proccess user's choice
})
processRedirects = function(action) {
.then(function(action) {
if ( action === 'accept' ) {
// Update discussion pages to use targets (for the ones that are redirects)
// Build a reference object linking titles to their page ids
var title_idsapiResponsePages = {}arrayFromResponsePages(result);
self.discussion.pages = self.discussion.pages.map(function(page) {
for (var tt=0; tt<result.query.pageids.length; tt++) {
title_ids[var result.query.pageids[tt] ]redirection = result.query.pages[ resultredirects.query.pageids[tt]find(function(redirect) ].title;{
return redirect.from === page.getPrefixedText();
}
});
// Update discussion's page data
if ( !redirection ) {
self.discussion.pages = self.discussion.pages.map(function(p) {
return page;
var rIndex = $.inArray(p.getTitle(), redir_from);
if ( rIndex === -1 ) {
// This is not a redirect
return p;
} else {
// This is a redirect - create new page object for target
var targetPage = Page.newFromText(redir_to[rIndex]);
var targetId = extraJs.val2key(redir_to[rIndex], title_ids);
targetPage.exists = targetId > 0;
targetPage.talkExists = result.query.pages[targetId].talkid > 0;
return targetPage;
}
var target = apiResponsePages.find(function(p) {
return p.title === redirection.to;
});
var targetTitle = mw.Title.newFromText(target.title);
setExistence(targetTitle, target.pageid > 0);
setExistence(targetTitle.getTalkPage(), target.talkid > 0);
return targetTitle;
});
//return Execute callbacktrue;
callback.call(self);
} else if ( action === 'reject' ) {
// JustNo getneed onto withupdate it:discussion's execute callbackpage data
callback.call(self)return true;
} else {
// Abort closing, reset discussion links
self.discussion.showLinks();
return $.Deferred().reject('Cancelled by user');
}
});
// Ask for user confirmation
extraJs.multiButtonConfirm('Use redirects or targets?', redirects_msg, [
{ label: 'कैंसिल', flags: 'safe' },
{ label: 'अनुप्रेषण इस्तेमाल करीं', action: 'reject' },
{ label: 'टारगेट इस्तेमाल करीं', action: 'accept', flags: 'progressive' }
], processRedirects, {'verbose': true, 'unescape': true, 'wikilinks': true} );
 
} else {
// No redirects present, just get on with it: execute callback
return true;
callback.call(self);
}
});
// Get redirect status / targets, if any, from Api
API.get( {
action: 'query',
titles: self.discussion.getPageTitles().join('|'),
redirects: 1,
prop: 'info',
inprop: 'talkid',
indexpageids: 1
} ).done( processPages )
.fail( function() {
// TODO....
} );
};
 
Line 2,682 ⟶ 3,325:
self.afdLogEditIndex = config.track.afdLogEdit.push($.Deferred()) - 1;
// Notify user
self.discussion.setStatus('इतंजार करत बाWaiting... (संपादन अंतरबिरोधto सेavoid बचावedit खातीconflicts, पहिलकीprevious रीलिस्टिंगrelistings '+
'need to be completed)');
'के पूरा होखल जरूरी बा)');
break;
case 'mfd':
Line 2,691 ⟶ 3,334:
Array.prototype.push.apply(self.tasks, [
new Task('updateOldLogPage', self.discussion),
new Task('updateNewLogPage', self.discussion),
( !self.discussion.isBasicMode() && self.discussion.pages.length > 1 )
]);
? new Task('updateNomTemplates', self.discussion)
: ''
]
.filter(function(v){ return !!v; })
);
break;
default: // ffd, tfd
Line 2,698 ⟶ 3,346:
new Task('updateOldLogPage', self.discussion),
new Task('updateNewLogPage', self.discussion),
( !self.discussion.pagesisBasicMode() ) ? new Task('updateNomTemplates', self.discussion) : ''
]
.filter(function(v){ return !!v; })
Line 2,718 ⟶ 3,366:
self.inputData.inPageActions('keep') ||
self.inputData.inPageActions('redirect') ||
( self.inputData.inPageActions('बिलय कइल जायmerge') && config.xfd.type !== 'tfd' ) ||
self.inputData.inPageActions('disambig')
) {
self.tasks.push(new Task('addOldXfd',
self.discussion, self.inputData.getPages(
'keep', 'redirect', ( /(afd|mfd)/.test(config.xfd.type) ) ? 'बिलय कइल जायmerge' : 'disambig'
)
));
Line 2,738 ⟶ 3,386:
}
// For merge (not holding cell) results:
if ( config.xfd.type !== 'tfd' && self.inputData.inPageActions('बिलय कइल जायmerge') ) {
self.tasks.push(new Task('addMergeTemplates',
self.discussion, self.inputData.getPages('बिलय कइल जायmerge')));
}
// For disambiguate results:
Line 2,763 ⟶ 3,411:
// For TfD holding cell results
if ( config.xfd.type === 'tfd' ) {
var doHcMerge = self.inputData.inPageActions('बिलय कइल जायmerge');
var doHcDelete = self.inputData.inPageActions('del') && self.inputData.useHoldingCell;
if ( doHcMerge && doHcDelete ) {
Line 2,769 ⟶ 3,417:
Array.prototype.push.apply(self.tasks, [
new Task('addBeingDeleted', self.discussion,
self.inputData.getPages('बिलय कइल जायmerge', 'del')),
new Task('addToHoldingCell', self.discussion,
self.inputData.getPages('बिलय कइल जायmerge', 'del')),
( self.inputData.dontdeletetalk ) ? null : new Task('tagTalkWithSpeedy',
self.discussion, self.inputData.getPages('बिलय कइल जायmerge', 'del'))
]
.filter(function(v){ return !!v; })
Line 2,780 ⟶ 3,428:
// Only 'merge' (via holding cell) results
Array.prototype.push.apply(self.tasks, [
new Task('addBeingDeleted', self.discussion, self.inputData.getPages('बिलय कइल जायmerge')),
new Task('addToHoldingCell', self.discussion, self.inputData.getPages('बिलय कइल जायmerge'))
]
);
Line 2,884 ⟶ 3,532:
$.each(self.tasks.slice(1), function(_i, t) {
if ( t.start ) {
t.start(); // TODO: set task status, errors, and warning here, from the returned promise
t.start();
} else { // TODO: Investigate what the point of this is.
} else {
self.tasks[_i+1].start();
}
Line 2,903 ⟶ 3,551:
$.when( config.track.afdLogEdit[self.afdLogEditIndex-1] )
.then( function() {
self.discussion.setStatus('रिलिस्ट कइल जात बाRelisting...');
self.tasks[0].start();
} );
Line 2,914 ⟶ 3,562:
var self = this;
 
var sanityCheckWarnings = self.makeSanityCheckWarnings();
// Initialise
$.when(
var doAfterSanityCheck = function(action) {
( sanityCheckWarnings )
? multiButtonConfirm({
title: 'Warning',
message: sanityCheckWarnings,
actions: [
{ label: 'Cancel', flags: 'safe' },
{ label: 'Continue', action: 'proceed', flags: 'progressive' }
],
size: 'large'
})
: $.Deferred().resolve('proceed')
)
.then(function(action) {
if ( action !== 'proceed' ) {
// Reset discussion links
Line 2,921 ⟶ 3,582:
return;
}
// Resolve redirects, then initialise...
ifreturn ( !self.inputData.result resolveRedirects() {;
})
self.resolveRedirects(self.initialiseForRelist);
.then(function(okayToProceed) {
if ( !okayToProceed ) {
return;
}
// ... then initialise
var isRelisting = !self.inputData.result;
if ( isRelisting ) {
self.initialiseForRelist();
} else if ( self.inputData.multimode ) {
self.resolveRedirects(self.initialiseForMultimodeClose();
} else {
self.resolveRedirects(self.initialiseForClose();
}
});
// Sanity checks
var sanityCheckWarnings = self.makeSanityCheckWarnings();
if ( sanityCheckWarnings ) {
// Check with user before preceding
extraJs.multiButtonConfirm('चेतावनी', sanityCheckWarnings, [
{ label: 'कैंसिल', flags: 'safe' },
{ label: 'आगे बढ़ीं', action: 'proceed', flags: 'progressive' }
], doAfterSanityCheck, {'verbose': true, 'unescape': true, 'wikilinks':true} );
} else {
// No need to check before preceding
doAfterSanityCheck('proceed');
}
};
 
Line 2,956 ⟶ 3,612:
 
TaskManager.prototype.makeTaskNote = function(task) {
var $notice = $('<p>')
.addClass('xfdc-task-' + task.status)
.addClass(task.name)
Line 3,035 ⟶ 3,691:
switch ( taskname ) {
case 'closeDisc':
this.description = 'चर्चाClosing बंद कइल जात बाdiscussion';
break;
case 'addOldXfd':
this.description = 'वार्ताUpdating पन्नाtalk अपडेट कइल जात बाpage' + (( plural ) ? 's' : '');
break;
case 'removeNomTemplates':
case 'addMergeTemplates':
case 'disambiguate':
this.description = 'पन्नाUpdating अपडेट कइल जात बाpage' + (( plural ) ? 's' : '');
break;
case 'peformDeletion':
this.description = 'पन्नाDeleting हटावल जात बाpage' + (( plural ) ? 's' : '');
break;
case 'addBeingDeleted':
this.description = 'टेम्पलेटUpdating अपडेट कइल जात बाtemplate' + (( plural ) ? 's' : '');
break;
case 'addToHoldingCell':
this.description = 'होल्डिंगListing सेलat मेंholding लिस्ट कइल जात बाcell';
break;
case 'deleteTalk':
this.description = 'वार्ताDeleting पन्नाtalk हटावल जात बाpage' + (( plural ) ? 's' : '');
break;
case 'tagTalkWithSpeedy':
this.description = 'वार्ताTagging पन्नाtalk टैग कइल जात बाpage' + (( plural ) ? 's' : '') +
' for speedy deletion';
break;
case 'deleteRedirects':
this.description = 'अनुप्रेषणDeleting हटावल जात बाredirects';
break;
case 'unlinkBacklinks':
this.description = 'कड़ीUnlinking तूरल जात बाbacklinks';
break;
case 'redirect':
if ( discussion.dialog.inputData.deleteFirst ) {
this.description = 'हटावलDeleting जात बा पन्नाpage' + (( plural ) ? 'सभs' : '') +
' and अनुप्रेषणreplacing with redirect' + (( plural ) ? 'सभs' : '') + 'से बदलल जात बा';
} else if ( config.xfd.type === 'rfd' ) {
this.description = 'अनुप्रेषणRetargeting redirect' + (( plural ) ? 'सभs' : '') + ' में बदलल जात बा';
} else {
this.description = 'पन्नाMaking page' + (( plural ) ? 'सभs' : '') +
' केinto अनुप्रेषणredirect' + (( plural ) ? 'सभs' : '') +' में बदलल जात बा';
}
break;
case 'removeCircularLinks':
this.description = 'Unlinking circular links on redirect target';
this.description = 'अनुप्रेषण टारगेट पर चक्राकार अनुप्रेषण हटावल जाता';
break;
case 'getRelistInfo':
this.description = 'रीलिस्टPreparing केto तइयारी होत बाrelist';
break;
case 'updateDiscussion':
this.description = 'चर्चाUpdating अपडेट कइल जात बाdiscussion';
break;
case 'updateOldLogPage':
this.description = 'पुरनकाRemoving लॉगfrom पन्नाold सेlog हटावल जात बाpage';
break;
case 'updateNewLogPage':
this.description = 'आजAdding केto लॉगtoday\'s पन्नाlog पर जोड़ल जात बाpage';
break;
case 'updateNomTemplates':
this.description = 'नामांकितUpdating पन्नाlink मेंin कड़ीnomination अपडेट कइल जात बाtemplate' +
(( plural ) ? 's' : '');
break;
Line 3,113 ⟶ 3,769:
var self = this;
this.status = s;
this.discussion.taskManager.updateTaskNotices(self);
};
Task.prototype.updateStatus = function() {
var self = this;
this.discussion.taskManager.updateTaskNotices(self);
};
Line 3,120 ⟶ 3,780:
// Not yet started:
case 'waiting':
return 'इंतजार कइल जाताWaiting...';
// In progress:
case 'started':
returnvar $msg = $('<imgspan>').attrappend({
$('<img>').attr({
'src':'//upload.wikimedia.org/wikipedia/commons/thumb/f/f8/Ajax-loader%282%29.gif/'+
'40px-src':'//upload.wikimedia.org/wikipedia/commons/thumb/f/f8/Ajax-loader%282%29.gif/',+
'40px-Ajax-loader%282%29.gif',
'width':'20',
'heightwidth':'520',
'height':'5'
});
})
);
if ( self.showTrackingProgress ) {
var counts = this.tracking[self.showTrackingProgress];
$msg.append(
$('<span>')
.css('font-size', '88%')
.append(
'&nbsp;(' +
(counts.success + counts.skipped) +
'&thinsp;/&thinsp;' +
counts.total +
')'
)
);
}
return $msg;
// Finished:
case 'done':
Line 3,137 ⟶ 3,814:
self.discussion.taskManager.dfd.initialTask.resolve();
}
return 'पूरा भइलDone!';
case 'aborted':
return 'छोड़ल गइल (एबोर्ट)।';
case 'failed':
return 'बिफल भइल।';
case 'skipped':
return extraJs.toSentenceCase(self.status) + '.';
return 'छोड़ दिहल गइल।';
default:
// unknown
Line 3,188 ⟶ 3,863:
};
};
Task.prototype.track = function(key, success, amount) {
if ( success ) {
this.tracking[key].success++=(amount||1);
} else {
this.tracking[key].skipped++=(amount||1);
}
 
if ( key === this.showTrackingProgress ) {
this.updateStatus();
}
 
if ( this.tracking[key].skipped === this.tracking[key].total ) {
this.tracking[key].dfd.reject();
Line 3,203 ⟶ 3,883:
 
Task.prototype.start = function() {
return this.doTask[this.name](this);
};
 
// Code to actually do the tasks
Task.prototype.doTask = {};
// ---------- Closing tasks -------------
// Close discussion
Task.prototype.doTask.closeDisc = function(self) {
// Notify task is started -- current (to-be-deprecated) method
self.setStatus('started');
// Get nomination page content and remove {Closing} etc templates if present
// Make top and bottom wikitext
return API.get( {
var xfd_close_top = config.xfd.wikitext.closeTop
action: 'query',
.replace(/__RESULT__/, self.inputData.getResult() || '&thinsp;')
titles: self.discussion.nomPage,
.replace(/__TO_TARGET__/, ( self.inputData.getTarget() ) ? ' जेकर टारगेट ' +
prop: 'revisions',
self.inputData.getTargetLink() : '')
rvprop: 'content|timestamp',
.replace(/__RATIONALE__/, ( self.inputData.getRationale() || '।'))
rvsection: self.discussion.sectionNumber,
.replace(/__SIG__/, config.user.sig);
indexpageids: 1
var editsum = '/* ' + self.discussion.sectionHeader + ' */ बंद कइल गइल, रिजल्ट: ' +
} )
self.inputData.getResult() + config.script.advert;
.then( function(response) {
var id = response.query.pageids;
 
return response.query.pages[ id ].revisions[ 0 ];
// Callback functions for processing api results
} )
processNomPage = function (result) {
.then( function(revision) {
var id = result.query.pageids;
var contents = result.query.pagesrevision[ id ].revisions[ 0 ][ '*' ];
var lastEditTime = revision.timestamp;
if ( contents.includes(config.xfd.wikitext.alreadyClosed) ) {
return $.Deferred().reject('aborted', null, 'Discussion already closed (reload page to see '+
self.discussion.taskManager.abortTasks('चर्चा पहिलहीं बंद हो चुकल बा (वास्तविक समापन देखे खातिर '+
'पन्नाthe रीलोडactual करींclose)');
return;
}
/* Start-time check only possible for AFDs/MFDs. Other venues have multiple discussions on
* the same page, which would give false-positives when a different section was edited.
*/
if ( config.xfd.type === 'afd' || config.xfd.type === 'mfd' ) {
var editedSinceScriptStarted = config.startTime < new Date(lastEditTime);
if ( editedSinceScriptStarted ) {
return $.Deferred().reject('aborted: edit conflict detected');
}
}
 
var section_heading = contents.slice(0, contents.indexOf('\n'));
var decodeHtml = function(t) {
return $('<div>').html(t).text();
};
var plain_section_heading = decodeHtml( section_heading
.replace(/(?:^\s*=*\s*|\s*=*\s*$)/g, '') // remove heading markup
.replace(/\[\[\:?(?:[^\]]+\|)?([^\]]+)\]\]/g, '$1') // replace link markup with link text
.replace(/{{\s*[Tt]l[a-z]?\s*\|\s*([^}]+)}}/g, '{{$1}}') // replace tl templates
.replace(/s*}}/, '}}') // remove any extra spaces after replacing tl templates
.replace(/\s{2,}/g, ' ') // collapse multiple spaces into a single space
.trim()
);
var isCorrectSection = plain_section_heading === self.discussion.sectionHeader;
if ( !isCorrectSection ) {
return $.Deferred().reject('aborted: possible edit conflict (found section heading `' +
plain_section_heading + '`)');
}
 
var xfd_close_top = config.xfd.wikitext.closeTop
.replace(/__RESULT__/, self.inputData.getResult() || '&thinsp;')
.replace(/__TO_TARGET__/, ( self.inputData.getTarget() ) ? ' to ' +
self.inputData.getTargetLink() : '')
.replace(/__RATIONALE__/, ( self.inputData.getRationale() || '.'))
.replace(/__SIG__/, config.user.sig);
var section_contents = contents.slice(contents.indexOf('\n')+1)
.replace(
/({{closing}}|{{AfDh}}|{{AfDb}}|\{\{REMOVE THIS TEMPLATE WHEN CLOSING THIS AfD\|.?\}\}|<noinclude>\[\[Category:Relisted AfD debates\|.*?\]\](\[\[Category:AfD debates relisted 3 or more times|.*?\]\])?<\/noinclude>)/gi,
'');
var updated_top = ( config.xfd.type === 'afd' || config.xfd.type === 'mfd' ) ?
var updated_section = '';
xfd_close_top + '\n' + section_heading :
if ( config.xfd.type === 'afd' || config.xfd.type === 'mfd' ) {
section_heading + '\n' + xfd_close_top;
updated_section = xfd_close_top + '\n' + section_heading + '\n' +
var updated_section = updated_top + '\n' + section_contents.trim() + '\n' + config.xfd.wikitext.closeBottom;
} else {
return $.Deferred().resolve(updated_section, lastEditTime);
updated_section = section_heading + '\n' + xfd_close_top + '\n' +
} )
section_contents.trim() + '\n' + config.xfd.wikitext.closeBottom;
.then( function(updated_section, lastEditTime) {
}
return API.postWithToken( 'csrf', {
// Perform edit to close XFD discussion
API.postWithToken( 'csrf', {
action: 'edit',
title: self.discussion.nomPage,
section: self.discussion.sectionNumber,
text: updated_section,
summary: '/* ' + self.discussion.sectionHeader + ' */ Closed as ' +
summary: editsum
self.inputData.getResult() + config.script.advert,
} )
basetimestamp: lastEditTime
.done( function() {
self.setStatus('done');
} )
.fail( function(code, jqxhr) {
self.addApiError(code, jqxhr,
[ 'पन्ना पर संपादन ना कइल जा सकल ',
extraJs.makeLink(self.discussion.nomPage),
'; चर्चा बंद ना कइल जा सकल' ]
);
self.discussion.taskManager.abortTasks('');
} );
};
// Get nomination page content and remove {Closing} etc templates if present
API.get( {
action: 'query',
titles: self.discussion.nomPage,
prop: 'revisions',
rvprop: 'content',
rvsection: self.discussion.sectionNumber,
indexpageids: 1
} )
.then(
.done( processNomPage )
.fail( function(code, jqxhr) {
self.setStatus('done'); // Current (to-be-deprecated) method of setting status
self.addApiError(code, jqxhr,
return 'done'; // Future method of setting status
[ 'पन्ना के सामग्री ना पढ़ल जा सकल ',
},
function(code, jqxhr, abortReason) {
var message = [
'Could not edit page ',
extraJs.makeLink(self.discussion.nomPage),
'; could not close discussion'
'; चर्चा बंद ना कइल जा सकल' ]
) ];
self.addApiError(code, jqxhr, message);
self.discussion.taskManager.abortTasks('');
var abortMessage = ( code.indexOf("aborted") === 0 && abortReason ) || '';
} );
self.discussion.taskManager.abortTasks(abortMessage);
return $.Deferred().reject(code, jqxhr, message);
}
);
 
};
Line 3,295 ⟶ 4,002:
// Notify task is started
self.setStatus('started');
 
// Function to make an edit with the api.
// Mode can be 'text' (overwrite existing content) or 'appendtext' or 'prependtext'
var apiEditTalk = function (pageTitle, newWikitext, mode, redirect) {
var req = {
action: 'edit',
title: pageTitle,
section: '0',
summary: 'Old ' + config.xfd.type.toUpperCase() + ' – ' + self.discussion.nomDate +
': ' + self.inputData.getResult() + config.script.advert,
redirect: !!redirect
};
req[mode] = ( mode === 'appendtext' ) ? '\n' + newWikitext : newWikitext;
API.postWithToken( 'csrf', req )
.done( function() {
self.track('processed', true);
})
.fail( function(code, jqxhr) {
self.track('processed', false);
self.addApiError(code, jqxhr, [
'वार्ता पन्ना पर संपादन ना कइल जा सकल ',
extraJs.makeLink(pageTitle)
]);
} );
};
 
// Make wikitext of olf xfd template (non-AFD)
var makeOldxfdWikitext = function(altpage) {
var result = config.xfd.wikitext.oldXfd
.replace(/__DATE__/, self.discussion.nomDate)
.replace(/__SECTION__/, self.discussion.sectionHeader)
Line 3,340 ⟶ 4,023:
var titleObject = mw.Title.newFromText(pageTitle);
var PAGENAME = titleObject.getMain();
var SUBJECTPAGENAME = config.mw.monthNames[(titleObject.getNamespaceId()-1).toString()] +
PAGENAME;
var oldafdmulti = '{{Old AfD multi';
Line 3,413 ⟶ 4,096:
var oldTfdDate = oldTfdParams.date;
var oldTfdResult = oldTfdParams.result || 'keep';
var oldTfdLink = "{{subst:#ifexist:विकिपीडियाWikipedia:हटावेTemplates खातिरfor टेम्पलेटdeletion/लॉगLog/"+
( oldTfdParams.link || "{{subst:Date|"+oldTfdParams.date+"|ymd}}" )+
"|Wikipedia:Templates for deletion/Log/" +
"|विकिपीडिया:हटावे खातिर टेम्पलेट/लॉग/" +
( oldTfdParams.link || "{{subst:Date|"+oldTfdParams.date+"|ymd}}" )+
"#" + ( oldTfdParams['1'] || oldTfdParams.disc || "टेम्पलेटTemplate:"+PAGENAME )+
"|Wikipedia:Templates for discussion/Log/"+
"|विकिपीडिया:चर्चा खातिर टेम्पलेट/लॉग/"+
( oldTfdParams.link || "{{subst:Date|"+oldTfdParams.date+"|ymd}}" )+
"#" + ( oldTfdParams['1'] || oldTfdParams.disc || "टेम्पलेटTemplate:"+PAGENAME )+
"}}";
oldafdmulti += " |date" + count + "=" + oldTfdDate +
Line 3,438 ⟶ 4,121:
var oldFfdDate = oldFfdParams.date || '';
var oldFfdResult = oldFfdParams.result || 'keep';
var oldFfdLink = "{{subst:#ifexist:विकिपीडियाWikipedia:Images and media for deletion/"+
"{{subst:#iferror:{{subst:#time:|"+oldFfdParams.date+"}}|"+oldFfdParams.date+
"|{{subst:#time:Y F j|"+oldFfdParams.date+"}}}}"+
"|विकिपीडियाWikipedia:Images and media for deletion/{{subst:#iferror:{{subst:#time:|"+
oldFfdParams.date+"}}|"+oldFfdParams.date+"|{{#time:Y F j|"+oldFfdParams.date+
"}}}}#File:" + ( oldFfdParams.page || PAGENAME ) +
"|{{subst:#ifexist:विकिपीडियाWikipedia:हटावेFiles खातिरfor फाइलdeletion/{{subst:#iferror:{{subst:#time:|"+
oldFfdParams.date+"}}|"+oldFfdParams.date+"|{{subst:#time:Y F j|"+
oldFfdParams.date+"}}}}"+
"|विकिपीडियाWikipedia:हटावेFiles खातिरfor फाइलdeletion/{{subst:#iferror:{{subst:#time:|"+oldFfdParams.date+"}}|"+
oldFfdParams.date+"|{{subst:#time:Y F j|"+oldFfdParams.date+"}}}}#" +
( oldFfdParams.page || SUBJECTPAGENAME )+
"|विकिपीडियाWikipedia:चर्चाFiles खातिरfor फाइलdiscussion/{{subst:#iferror:{{subst:#time:|"+oldFfdParams.date+"}}|"+
oldFfdParams.date+"|{{subst:#time:Y F j|"+oldFfdParams.date+"}}}}#" +
( oldFfdParams.page || SUBJECTPAGENAME )+
Line 3,471 ⟶ 4,154:
var oldMfdDate = oldMfdParams.date || '';
var oldMfdResult = oldMfdParams.result || 'keep';
var oldMfdLink = "विकिपीडियाWikipedia:हटावेMiscellany खातिरfor बिबिधdeletion/" +
( oldMfdParams.votepage || oldMfdParams.title ||
oldMfdParams.page || SUBJECTPAGENAME );
Line 3,495 ⟶ 4,178:
oldRfdLink = oldRfdParams.rawlink.slice(2, oldRfdParams.rawlink.indexOf('|'));
} else {
oldRfdLink = "विकिपीडियाWikipedia:चर्चाRedirects खातिरfor अनुप्रेषणdiscussion/लॉगLog/" +
( oldRfdParams.page || oldRfdParams.date + "#" + SUBJECTPAGENAME );
}
Line 3,531 ⟶ 4,214:
oldafdmulti += ' |date'+c + '=' + self.discussion.nomDate +
' |result'+c+ "='''" + currentResult + "'''" + currentNompageParamAndValue + '}}';
var newtext;
if ( oldAfdPatt.test(wikitext) ) {
// Override the existing oldafdmulti
Line 3,540 ⟶ 4,224:
return newtext;
};
 
// Get talk pages
var confirmRedirectReplacement = function(talkTitle) {
var talkTitles = self.discussion.getTalkTitles(self.pages);
OO.ui.confirm('"' + talkTitle + '" वर्तमान में अनुप्रेषण बा। ठीक बा ' +
if ( talkTitles.length === 0 ) {
'कि Old RFD template से बदल दिहल जाय?')
self.addWarning('none found');
.done( function ( confirmed ) {
self.setStatus('done');
if ( confirmed ) {
return;
// Make the edit, replacing previous content
}
apiEditTalk(talkTitle, makeOldxfdWikitext(), 'text');
// get talk page redirect status from api
self.setupTracking('processed', talkTitles.length);
// Function to transform a simplified API page object into edit parameters for API.editWithRetry
var transform = function(page) {
// Check there's a corresponding nominated page
var pageObj = self.discussion.getPageByTalkTitle(page.title);
if ( !pageObj ) {
return $.Deferred().reject("Unexpected title");
}
// Check corresponding page exists
if ( !pageObj.exists() ) {
return $.Deferred().reject("Subject page does not exist");
}
var baseEditParams = {
section: '0',
summary: 'Old ' + config.xfd.type.toUpperCase() + ' – ' + self.discussion.nomDate +
': ' + self.inputData.getResult() + config.script.advert,
};
// Check redirect status
if ( config.xfd.type !== 'afd' && page.redirect ) {
// Is a redirect...
if ( config.xfd.type === 'rfd' ) {
// for RFD, ask what to do
return OO.ui.confirm('"' + page.title + '" is currently a redirect. Okay ' +
'to replace with Old RFD template?')
.then( function ( confirmed ) {
if (!confirmed) {
return $.Deferred().reject('skipped');
}
return $.extend(baseEditParams, {
text: makeOldxfdWikitext(),
redirect: false
});
} );
} else if ( config.xfd.type === 'mfd' ) {
// For MFD, edit the redirect's target page, using the altpage parameter
return $.extend(baseEditParams, {
prependtext: makeOldxfdWikitext(pageObj.getPrefixedText()),
redirect: true
});
} else {
// For other venues, append rather than prepend old xfd template
// Skip
return $.extend(baseEditParams, {
self.addWarning([
appendtext: '\n' + makeOldxfdWikitext(),
extraJs.makeLink(talkTitle),
redirect: false
' छोड़ल गइल'
]});
self.track('processed', true);
}
} );else {
// Not a redirect. Attempt to find and consolidate existing banners
var oldwikitext = page.missing ? '' : page.content;
return $.extend(baseEditParams, {
text: makeNewWikitext(oldwikitext, page.title),
redirect: false,
});
}
};
API.editWithRetry(
var processTalkTitles = function (result) {
talkTitles,
var page_ids = result.query.pageids;
{rvsection: '0'},
for ( var i=0; i < page_ids.length; i++ ) {
transform,
var talkTitle = result.query.pages[ page_ids[i] ].title;
function() { self.track('processed', true); },
// Check there's a corresponding nominated page
function(code, error, title) {
var pageObj = self.discussion.getPageByTalkTitle(talkTitle);
if switch( !pageObj code) {
case "Unexpected title":
self.addError([
self.addError([
'एपीआइ क्वैरीरिजल्ट में अनचिन्हुआ वार्ता पन्ना टाइटिल बा ',
'API query result included unexpected talk page title ',
extraJs.makeLink(talkTitle),
extraJs.makeLink(title),
'; एह वार्ता पन्ना पर संपादन ना कइल जाई'
'; this talk page will not be edited'
]);
]);
self.track('processed', false);
continue break;
case "Subject page does not exist":
}
self.addError([
// Check corresponding page exists
'The subject page for ',
if ( !pageObj.exists ) {
extraJs.makeLink(title),
self.addError([
' does not exist; this talk page will not be edited'
'बिसय पन्ना ',
]);
extraJs.makeLink(talkTitle),
self.track('processed', false);
' खातिर मौजूद नइखे; एह वार्ता पन्ना पर संपादन ना कइल जाई'
]) break;
case "skipped":
self.track('processed', false);
self.addWarning([
continue;
extraJs.makeLink(title),
}
' skipped'
// Check redirect status
]);
if ( config.xfd.type !== 'afd' && result.query.pages[ page_ids[i] ].redirect === '' ) {
self.track('processed', true);
// Is a redirect...
break;
if ( config.xfd.type === 'rfd' ) {
default:
// for RFD, ask what to do
self.addApiError(code, error, [
confirmRedirectReplacement(talkTitle);
'Could not edit talk page ',
} else if ( config.xfd.type === 'mfd' ) {
extraJs.makeLink(title)
// For MFD, edit the redirect's target page, using the altpage parameter
]);
apiEditTalk(talkTitle, makeOldxfdWikitext(pageObj.getTitle()),
self.track('prependtextprocessed', truefalse);
} else {
// For other venues, append rather than prepend old xfd template
apiEditTalk(talkTitle, makeOldxfdWikitext(), 'appendtext');
}
} else {
// Not a redirect. Attempt to find and consolidate existing banners
var oldwikitext = '';
if ( parseInt(page_ids[i]) > 0 ) {
oldwikitext = result.query.pages[ page_ids[i] ].revisions[0]['*'];
}
apiEditTalk(talkTitle, makeNewWikitext(oldwikitext, talkTitle), 'text');
}
}
).fail( function(errortype, code, jqxhr) {
if ( errortype === "read" ) {
};
self.addApiError(code, jqxhr, 'Could not read contents of talk page' +
( talkTitles.length > 1 ) ? 's' : '');
// Get talk pages
var talkTitles = self.discussion.getTalkTitles(self.pages);
if ( talkTitles.length === 0 ) {
self.addWarning('एकहू ना मिलल');
self.setStatus('पूरा भइल');
} else {
// get talk page redirect status from api
self.setupTracking('processed', talkTitles.length);
API.get( {
action: 'query',
prop: 'revisions|info',
rvprop: 'content',
rvsection: '0',
titles: talkTitles,
indexpageids: 1
} )
.done( processTalkTitles )
.fail( function(code, jqxhr) {
self.addApiError(code, jqxhr, 'वार्ता पन्ना' +
( talkTitles.length > 1 ) ? 'सभ' : '') + ' के पढ़ल ना जा सकल'
self.setStatus('failed');
} // other errors handled above
} );
} );
};
 
Task.prototype.doTask.removeNomTemplates = function(self, mergeWikitext) {
 
// Notify task is started
self.setStatus('started');
 
// Get page titles
apiEditPage = function(pageTitle, updatedWikitext) {
var pageTitles = self.discussion.getPageTitles(self.pages, {'moduledocs': true});
API.postWithToken( 'csrf', {
action: 'edit',
title: pageTitle,
text: updatedWikitext,
summary: config.xfd.type.toUpperCase() + ' बंद कइल गइल ' +
self.inputData.getResult() + config.script.advert
} )
.done( function() {
self.track('edit', true);
} )
.fail( function(code, jqxhr) {
self.track('edit', false);
self.addApiError(code, jqxhr, [
'पन्ना पर संपादन ना कइल जा सकल ',
extraJs.makeLink(pageTitle)
]);
} );
};
var processPages = function (result) {
//Get old wikitext, or make error if page doesn't exist, or if page is in wrong namespace
var page_ids = result.query.pageids;
for (var i = 0; i < page_ids.length; i++) {
var pageTitle = result.query.pages[ page_ids[i] ].title;
// Check there's a corresponding nominated page
var pageObj = self.discussion.getPageByTitle(pageTitle);
if ( !pageObj ) {
self.addError([
'एपीआइ क्वैरी के रिजल्ट में अनचिन्हुआ टाइटिल मिलल ',
extraJs.makeLink(talkTitle),
'; ई पन्ना ना संपादित कइल जाई'
]);
self.track('edit', false);
continue;
}
// Check that page exists
if ( parseInt(page_ids[i]) < 0 ) {
self.addError([
extraJs.makeLink(talkTitle),
' मौजूद नइखे आ संपादित ना कइल जाई'
]);
self.track('edit', false);
continue;
}
 
// Existing wikitext
var oldWikitext = result.query.pages[ page_ids[i] ].revisions[0]['*'];
// Start building updated wikitext
var updatedWikitext = '';
// For merging, unless the page is itself a merge target, prepend the mergeWikitext
if (
mergeWikitext != null &&
$.inArray(pageTitle, self.inputData.getTargetsArray('बिलय कइल जाय')) === -1
) {
updatedWikitext = mergeWikitext[pageTitle];
}
// Remove nom template if present, or warn if not found
if ( config.xfd.regex.nomTemplate.test(oldWikitext) ) {
updatedWikitext += oldWikitext.replace(config.xfd.regex.nomTemplate, '');
} else {
self.addWarning([
'पन्ना पर नामांकन टेम्पलेट ना मिलल ',
extraJs.makeLink(pageTitle)
]);
if ( updatedWikitext === '' ) {
// Skip - nothing to change
self.track('edit', false);
continue;
} else {
updatedWikitext += oldWikitext;
}
}
// Make the edit
apiEditPage(pageTitle, updatedWikitext);
}
};
 
//get each page's wikitext through api
var pageTitles = self.discussion.getPageTitles(self.pages);
if ( pageTitles.length === 0 ) {
self.addWarning('एकहूnone ना मिललfound');
self.setStatus('बिफलfailed');
return;
}
Line 3,739 ⟶ 4,359:
);
 
// Function to transform a simplified API page object into edit parameters for API.editWithRetry
API.get( {
var transform = function(page) {
action: 'query',
// Check there's a corresponding nominated page
titles: pageTitles.join('|'),
var pageObj = self.discussion.getPageByTitle(page.title, {'moduledocs': true});
prop: 'revisions',
if ( !pageObj ) {
rvprop: 'content',
return $.Deferred().reject("unexpectedTitle");
indexpageids: 1,
}
rawcontinue: ''
// Check corresponding page exists
} )
if ( !pageObj.exists() ) {
.done( processPages )
return $.Deferred().reject("doesNotExist");
.fail( function(code, jqxhr) {
}
self.addApiError(code, jqxhr, 'नामांकित पन्ना' +
var oldWikitext = page.content;
( pageTitles.length > 1 ) ? 'सभ' : '') + ' के सामग्री पढ़ल ना जा सकल';
self.setStatus('failed');
// Start building updated wikitext
var updatedWikitext = '';
// For merging, unless the page is itself a merge target, prepend the mergeWikitext
if (
mergeWikitext != null &&
$.inArray(page.title, self.inputData.getTargetsArray('merge')) === -1
) {
updatedWikitext = mergeWikitext[page.title];
}
if ( config.xfd.hasNomTemplate(oldWikitext) ) {
try {
// Remove nom template
updatedWikitext += config.xfd.removeNomTemplate(oldWikitext);
} catch(e){
// Error if multiple nom templates found
return $.Deferred().reject("couldNotUpdate", e);
}
} else {
// Nomination template not found
if ( updatedWikitext === '' ) {
// Skip - nothing to change
return $.Deferred().reject("nominationTemplateNotFound");
} else {
// Show warning
self.addWarning([
'Nomination template not found on page ',
extraJs.makeLink(page.title)
]);
// Keep going - can still prepend wikitext for merging
updatedWikitext += oldWikitext;
}
}
return {
text: updatedWikitext,
summary: config.xfd.type.toUpperCase() + ' closed as ' +
self.inputData.getResult() + config.script.advert
};
};
API.editWithRetry(
pageTitles,
null,
transform,
function() { self.track('edit', true); },
function(code, error, title) {
switch(code) {
case "unexpectedTitle":
self.addError([
'API query result included unexpected title ',
extraJs.makeLink(title),
'; this talk page will not be edited'
]);
self.track('edit', false);
break;
case "doesNotExist":
self.addError([
extraJs.makeLink(title),
' does not exist, and will not be edited'
]);
self.track('processed', false);
break;
case "nominationTemplateNotFound":
self.addWarning([
'Nomination template not found on page ',
extraJs.makeLink(title)
]);
self.track('edit', false);
break;
case "couldNotUpdate":
self.addError([
'Could not update ',
extraJs.makeLink(title),
': ',
error.message
]);
self.track('edit', false);
break;
default:
self.addApiError(code, error, [
'Could not edit page ',
extraJs.makeLink(title)
]);
self.track('edit', false);
}
}
).fail( function(errortype, code, jqxhr) {
if ( errortype === "read" ) {
self.addApiError(code, jqxhr, 'Could not read contents of nominated page' +
( pageTitles.length > 1 ) ? 's' : '');
self.setStatus('failed');
} // other errors handled above
} );
};
Line 3,761 ⟶ 4,473:
 
// Edit function
var editTargetTalk = function(pageTitle, prependWikitext, isRetry) {
API.postWithToken( 'csrf', {
action: 'edit',
title: pageTitle,
prependtext: prependWikitext,
summary: '[[:' + self.discussion.getNomPageLink() + ']] बंदclosed कइल गइलas ' +
self.inputData.getResult() + config.script.advert
} )
Line 3,773 ⟶ 4,485:
})
.fail( function(code, jqxhr) {
if (!isRetry) {
return editTargetTalk(pageTitle, prependWikitext, true);
}
self.track('editTargetTalk', false);
self.addApiError(code, jqxhr, [
Line 3,782 ⟶ 4,497:
// Get targets and their talk pages
var targets = extraJs.uniqueArray(self.inputData.getTargetsArray('बिलय कइल जायmerge'));
self.setupTracking('alldone', 2);
Line 3,795 ⟶ 4,510:
var debate = self.discussion.getNomSubpage();
var today = new Date();
var curdate = today.getUTCDate().toString() + ' ' + config.mw.monthNames[today.getUTCMonth()] + ' ' +
today.getUTCFullYear().toString();
Line 3,816 ⟶ 4,531:
.replace(/__DEBATE__/, debate)
.replace(/__DATE__/, curdate)
.replace(/__TARGETTALK__/, Pagemw.Title.newFromText(targets[i]).getTalkgetTalkPage().getPrefixedText());
 
// Make 'merge from' template for the target's talk page
Line 3,840 ⟶ 4,555:
} else {
// Edit target talkpage
editTargetTalk(Pagemw.Title.newFromText(targets[i]).getTalkgetTalkPage().getPrefixedText(), mergefromTemplates.join(''));
}
}
Line 3,850 ⟶ 4,565:
 
Task.prototype.doTask.disambiguate = function(self) {
 
// Notify task is started
self.setStatus('started');
 
var pageTitles = self.discussion.getPageTitles(self.pages);
apiEditPage = function(pageTitle, updatedWikitext) {
if ( pageTitles.length === 0 ) {
API.postWithToken( 'csrf', {
self.addWarning('none found');
action: 'edit',
self.setStatus('failed');
title: pageTitle,
return;
}
self.setupTracking('edit', pageTitles.length);
// Function to transform a simplified API page object into edit parameters for API.editWithRetry
var transform = function(page) {
// Check there's a corresponding nominated page
var pageObj = self.discussion.getPageByTitle(page.title, {'moduledocs': true});
if ( !pageObj ) {
return $.Deferred().reject("unexpectedTitle");
}
// Check corresponding page exists
if ( !pageObj.exists() ) {
return $.Deferred().reject("doesNotExist");
}
var oldWikitext = page.content;
var updatedWikitext = '';
 
if ( config.xfd.regex.fullNomTemplate.test(oldWikitext) ) {
updatedWikitext = oldWikitext.replace(config.xfd.regex.fullNomTemplate, '').trim();
} else {
self.addWarning([
'Nomination template not found on page ',
extraJs.makeLink(page.title)
]);
updatedWikitext = oldWikitext.replace(/^#REDIRECT/mi, '*');
}
if ( !/(?:disambiguation|disambig|dab|Mil-unit-dis|Numberdis)[^{]*}}/i.test(updatedWikitext) ) {
updatedWikitext += '\n{{Disambiguation cleanup|{{subst:DATE}}}}';
updatedWikitext.trim();
}
return {
text: updatedWikitext,
summary: config.xfd.type.toUpperCase() + ' बंदclosed कइल गइलas ' +
self.inputData.getResult() + config.script.advert
} );
.done( function() {
self.track('edit', true);
} )
.fail( function(code, jqxhr) {
self.track('edit', false);
self.addApiError(code, jqxhr, [
'पन्ना संपादित ना कइल जा सकल ',
extraJs.makeLink(pageTitle)
]);
} );
};
API.editWithRetry(
var processPages = function (result) {
pageTitles,
//Get old wikitext, or make error if page doesn't exist, or if page is in wrong namespace
null,
var page_ids = result.query.pageids;
transform,
for (var i = 0; i < page_ids.length; i++) {
function() { self.track('edit', true); },
var pageTitle = result.query.pages[ page_ids[i] ].title;
function(code, error, title) {
// Check there's a corresponding nominated page
switch(code) {
var pageObj = self.discussion.getPageByTitle(pageTitle);
case "unexpectedTitle":
if ( !pageObj ) {
self.addError([
'API query result included unexpected title ',
'एपीआई क्वैरी में अनचिन्हुआ टाइटिल ',
extraJs.makeLink(talkTitletitle),
'; this talk page will not be edited'
' मिलल; ई पन्ना संपादित ना कइल जाई'
]);
self.track('edit', false);
continue break;
case "doesNotExist":
self.addError([
extraJs.makeLink(title),
' does not exist, and will not be edited'
]);
self.track('processed', false);
break;
default:
self.addApiError(code, error, [
'Could not edit page ',
extraJs.makeLink(title)
]);
self.track('edit', false);
}
// Check that page exists
if ( parseInt(page_ids[i]) < 0 ) {
self.addError([
extraJs.makeLink(talkTitle),
' मौजूद नइखे आ संपादित ना कइल जाई'
]);
self.track('edit', false);
continue;
}
 
var oldWikitext = result.query.pages[ page_ids[i] ].revisions[0]['*'];
var updatedWikitext = '';
if ( config.xfd.regex.fullNomTemplate.test(oldWikitext) ) {
updatedWikitext = oldWikitext.replace(config.xfd.regex.fullNomTemplate, '').trim();
} else {
self.addWarning([
'पन्ना पर नामांकन टेम्पलेट ना मिलल ',
extraJs.makeLink(pageTitle)
]);
updatedWikitext = oldWikitext.replace(/^#REDIRECT/mi, '*');
}
if ( !/(?:disambiguation|disambig|dab|Mil-unit-dis|Numberdis)[^{]*}}/i.test(updatedWikitext) ) {
updatedWikitext += '\n{{Disambiguation cleanup|{{subst:DATE}}}}';
updatedWikitext.trim();
}
 
apiEditPage(pageTitle, updatedWikitext);
}
).fail( function(errortype, code, jqxhr) {
};
if ( errortype === "read" ) {
 
self.addApiError(code, jqxhr, 'Could not read contents of nominated page' +
//get each page's wikitext through api
var ( pageTitles.length => self.discussion.getPageTitles(self.pages1 ) ? 's' : '');
self.setStatus('failed');
if ( pageTitles.length === 0 ) {
} // other errors handled above
self.addWarning('एकहू ना मिलल');
self.setStatus('बिफल');
return;
}
self.setupTracking('edit', pageTitles.length);
 
API.get( {
action: 'query',
titles: pageTitles.join('|'),
prop: 'revisions',
rvprop: 'content',
indexpageids: 1,
rawcontinue: ''
} )
.done( processPages )
.fail( function(code, jqxhr) {
self.addApiError(code, jqxhr, 'नामांकित पन्ना' +
( pageTitles.length > 1 ) ? 'सभ' : '') + ' के सामग्री ना पढ़ल जा सकल';
self.setStatus('failed');
} );
};
Line 3,954 ⟶ 4,658:
// Delete with the api
var apiDeletePage = function(pageTitle, isRetry) {
API.postWithToken( 'csrf', {
action: 'delete',
Line 3,964 ⟶ 4,668:
} )
.fail( function(code, jqxhr) {
if (!isRetry) {
return apiDeletePage(pageTitle, true);
}
self.track('del', false);
self.addApiError(code, jqxhr, [
'Could not delete page ',
'पन्ना हटावल ना जा सकल ',
extraJs.makeLink(pageTitle)
]);
Line 3,976 ⟶ 4,683:
// For each page, check it exists, then delete with api or add warning
for ( var i=0; i<pages.length; i++ ) {
if ( pages[i].exists() ) {
apiDeletePage(pages[i].getTitlegetPrefixedText());
} else {
self.addWarning([
extraJs.makeLink(pages[i].getTitlegetPrefixedText()),
' skipped: does not exist (may have already been deleted by others)'
' छोड़ दिहल गइल: मौजूद नइखे (साइद केहू अउरी पहिलहीं हटा चुकल होखी)'
]);
self.track('del', false);
Line 3,996 ⟶ 4,703:
var mergeTargets = [];
var mergeTitles = [];
if ( self.inputData.inPageActions('बिलय कइल जायmerge') || self.inputData.result === 'बिलय कइल जायmerge' ) {
mergeTargets = self.inputData.getTargetsArray('बिलय कइल जायmerge');
mergeTitles = self.discussion.getPageTitles(
(self.inputData.multimode ) ? self.inputData.getPages('बिलय कइल जायmerge') : self.pages
);
}
 
var templateTitles = self.discussion.getPageTitles(self.pages, {'moduledocs': true});
// Edit with the Api
var apiEditTemplate = function(pageTitle, newWikitext, editsum) {
API.postWithToken( 'csrf', {
action: 'edit',
title: pageTitle,
text: newWikitext,
summary: editsum
} )
.done( function() {
self.track('edit', true);
} )
.fail( function(code, jqxhr) {
self.track('edit', false);
self.addApiError(code, jqxhr, [
'Could not edit page ',
extraJs.makeLink(pageTitle)
]);
} );
};
 
self.setupTracking('edit', templateTitles.length);
var processTemplates = function (result) {
 
var page_ids = result.query.pageids;
// Function to transform a simplified API page object into edit parameters for API.editWithRetry
for (var i = 0; i < page_ids.length; i++) {
var transform = function(page) {
var pageTitle = result.query.pages[ page_ids[i] ].title;
// Check there's a corresponding nominated page
var pageObj = self.discussion.getPageByTitle(page.title, {'moduledocs': true});
// Check there's a corresponding nominated page
if ( !pageObj ) {
var pageObj = self.discussion.getPageByTitle(pageTitle);
return $.Deferred().reject("unexpectedTitle");
if ( !pageObj ) {
}
self.addError([
// Check corresponding page exists
'API query result included unexpected page ',
if ( !pageObj.exists() ) {
extraJs.makeLink(pageTitle),
return $.Deferred().reject("doesNotExist");
'; ई पन्ना ना संपादित कइल जाई'
]);}
self.track('edit', false);
// Replace {Template for discussion/dated} or {Tfm/dated} (which
continue;
// may or may not be noincluded)
}
var isModule = ( page.title.indexOf('Module:') === 0 );
// Check that page exists
var inclusionTag = ( isModule ) ? 'includeonly' : 'noinclude';
if ( parseInt(page_ids[i]) < 0 ) {
var oldWikitext = page.content;
self.addError([
var updatedWikitext = '';
extraJs.makeLink(pageTitle),
var editsum = '';
' मौजूद नइखे (हटावल जा चुकल होखी)'
]);try {
if ( $.inArray(page.title, mergeTargets) !== -1 ) {
self.track('edit', false);
continue;
}
// Replace {Template for discussion/dated} or {Tfm/dated} (which
// may or may not be noincluded)
var oldWikitext = result.query.pages[ page_ids[i] ].revisions[0]['*'];
var updatedWikitext = '';
var editsum = '';
if ( $.inArray(pageTitle, mergeTargets) !== -1 ) {
// If this is a merge target, don't add anything - just remove nom template
updatedWikitext = oldWikitext.replace(config.xfd.regex.nomTemplate, ''removeNomTemplate(oldWikitext);
editsum = '[[' + self.discussion.getNomPageLink() + ']] closed as ' +
self.inputData.getResult() + config.script.advert;
} else if ( self.inputData.holdcell === 'ready' ) {
// If holding cell section is 'ready for deletion', tag for speedy deletion
updatedWikitext = '<noinclude' + inclusionTag + '>{{Db-xfd|fullvotepage=' +
self.discussion.getNomPageLink() + '}}</noinclude' + inclusionTag + '>' +
oldWikitext.replace(config.xfd.regex.nomTemplate, ''removeNomTemplate(oldWikitext);
editsum = '[[WP:G6|G6]] तुरंतSpeedy हटावेdeletion के नामांकनnomination, कारणper [[' +
self.discussion.getNomPageLink() + ']]' + config.script.advert;
} else {
// Add Being deleted template, remove nom template
updatedWikitext = '<noinclude' + inclusionTag + '>{{Being deleted|' + self.discussion.nomDate + '|' +
mw.util.wikiUrlencode(self.discussion.sectionHeader);
if ( $.inArray(pageTitlepage.title, mergeTitles) !== -1 ) {
// If being merged, set merge parameter
updatedWikitext += '|merge=' + self.inputData.getTarget(pageTitlepage.title);
}
updatedWikitext += '}}</noinclude' + inclusionTag + '>' + oldWikitext.replace(config.xfd.regex.nomTemplate, ''removeNomTemplate(oldWikitext);
editsum = 'Per [[' + self.discussion.getNomPageLink() + ']] अनुसार, '+
'added {{being deleted}} जोड़ल गइल' + config.script.advert;
}
} catch(e){
 
// Error if multiple nom templates found
// Make the edit
return $.Deferred().reject("couldNotUpdate", e);
apiEditTemplate(pageTitle, updatedWikitext, editsum);
}
return {
text: updatedWikitext,
summary: editsum
};
};
 
API.editWithRetry(
var templateTitles = self.discussion.getPageTitles(self.pages);
templateTitles,
 
null,
self.setupTracking('edit', templateTitles.length);
transform,
//get page wikitext through api
function() { self.track('edit', true); },
API.get( {
function(code, error, title) {
action: 'query',
switch(code) {
titles: templateTitles.join('|'),
case "unexpectedTitle":
prop: 'revisions',
self.addError([
rvprop: 'content',
'API query result included unexpected title ',
indexpageids: 1,
extraJs.makeLink(title),
rawcontinue: ''
'; this talk page will not be edited'
} )
]);
.done( processTemplates )
self.track('edit', false);
.fail( function(code, jqxhr) {
break;
self.addApiError(code, jqxhr, 'नामांकित पन्ना' +
case "doesNotExist":
( templateTitles.length > 1 ) ? 'सभ' : '' + ' के सामग्री ना पढ़ल जा सकल');
self.setStatusaddError('failed');[
extraJs.makeLink(title),
' does not exist, and will not be edited'
]);
self.track('processed', false);
break;
case "couldNotUpdate":
self.addError([
'Could not update ',
extraJs.makeLink(title),
': ',
error.message
]);
self.track('edit', false);
break;
default:
self.addApiError(code, error, [
'Could not edit page ',
extraJs.makeLink(title)
]);
self.track('edit', false);
}
}
).fail( function(errortype, code, jqxhr) {
if ( errortype === "read" ) {
self.addApiError(code, jqxhr, 'Could not read contents of nominated page' +
( templateTitles.length > 1 ) ? 's' : '');
self.setStatus('failed');
} // other errors handled above
} );
};
 
Line 4,112 ⟶ 4,821:
self.setStatus('started');
var holdCellSections = [
self.inputData.holdcell || null,
self.inputData.mergeHoldcell || null
Line 4,119 ⟶ 4,828:
.map(function(v){ return config.xfd.holdingCellSectionNumber[v]; });
self.setupTracking('processededit', holdCellSections.length1);
 
// Function to maketransform ana simplified API page object into edit parameters for API.editWithRetry
var apiEditHoldingCelltransform = function(newWikitext, sectionNumpage) {
API.postWithToken( 'csrf', {
action: 'edit',
title: config.xfd.subpagePath + 'Holding cell',
section: sectionNum,
text: newWikitext,
summary: 'टेम्पलेट सभ के [[' + self.discussion.getNomPageLink() + ']] के अनुसार लिस्ट में जोड़ल जात बा ' +
config.script.advert
} )
.done( function() {
self.track('processed', true);
})
.fail( function(code, jqxhr) {
self.track('processed', false);
self.addApiError(code, jqxhr, 'टेम्पलेट के होल्डिंग सेल में ना जोड़ल जा सकल');
} );
};
var processHoldingCellPage = function (result) {
var p_id = result.query.pageids;
// Get page contents, make all headings level 3 so sections can be counted
var updatedContent = page.content;
var p_contents = result.query.pages[ p_id ].revisions[0]['*'].replace(/====/gi, '===');
var sectionsArrayp_contents = p_contentspage.splitcontent.replace(/====/gi, '===');
var sectionsArray = p_contents.split('===');
for ( var i=0; i<holdCellSections.length; i++forEach(function(holdCellSection) {
var isMergeSection = (4 <= holdCellSections[i]holdCellSection) && ( holdCellSections[i]holdCellSection <= 10);
var listingPages;
Line 4,153 ⟶ 4,844:
listingPages = self.discussion.pages;
} else if ( isMergeSection ) {
listingPages = self.inputData.getPages('बिलय कइल जायmerge');
} else {
listingPages = self.inputData.getPages('del');
Line 4,159 ⟶ 4,850:
var tfdlTemplates = '';
for (ii = 0; ii < listingPages.length; ii++forEach(function(listingPage) {
//Check namespace and existance
if ( !listingPages[ii].hasCorrectNamespace(listingPage) ) {
self.addError([
extraJs.makeLink(listingPages[ii]listingPage),
' नाँवस्थानis not in the ' + config.mw.namespaces[config.xfd.ns_number[0].toString()] +
' namespace, and will not be listed at the holding cell'
' नइखे, आ होल्डिंग सेल में ना जोड़ल जाई'
]);
} else if ( !listingPages[ii]listingPage.exists() ) {
self.addError([
extraJs.makeLink(listingPages[ii]listingPage),
' does not exist, and will not be listed at the holding cell'
' मौजूद नइखे, आ होल्डिंग सेल में ना जोड़ल जाई'
]);
} else {
tfdlTemplates += '*{{tfdl|' + listingPages[ii]listingPage.getMain() + '|' +
'|' + self.discussion.nomDate +
'|section=' + self.discussion.sectionHeader +
(( holdCellSections[i]holdCellSection === 14 ) ? '|delete=1' : '') + '}}\n';
(( listingPage.getNamespaceId() === 828 ) ? '|ns=Module' : '') +
'}}\n';
}
});
if ( tfdlTemplates === '' ) {
// If all don't exist or are in wrong namespace, then there's nothing to do
self.track('processed', false);
continuereturn;
}
// Make new section wikitext
var heading = sectionsArray[(holdCellSections[i]holdCellSection*2-1)];
var contents = sectionsArray[(holdCellSections[i]holdCellSection*2)];
// Merge subsections have level-4 headings
var headingLevel = isMergeSection ? '====' : '===';
var oldSectionWikitext = headingLevel + heading + headingLevel + contents;
// Remove "* ''None currently''" except if inside a <!--html comment-->
contents = contents.replace(/\n*^\*\s*''None currently''\s*$(?![^<]*?-->)/gim, '');
var newSectionWikitext = headingLevel + heading + headingLevel + '\n' +
// Merge subsections have level-4 headings
var headingLevel = ( (4 <= holdCellSections[i]) &&
( holdCellSections[i] <= 10) ) ? '====' : '===';
var newWikitext = headingLevel + heading + headingLevel + '\n' +
contents.trim() + '\n' + tfdlTemplates;
updatedContent = updatedContent.replace(oldSectionWikitext, newSectionWikitext);
});
// If this isn't the first iteration of for-loop, wait a bit to avoid self-edit conflict
if ( i > 0 ) {
if (updatedContent === page.content) {
var start = new Date().getTime();
return $.Deferred().reject("noChangesMade");
var waited = 0;
}
while ( waited < 1000 ) {
waited = new Date().getTime() - start;
return {
}
text: updatedContent,
summary: 'Listing template(s) per [[:' + self.discussion.getNomPageLink() + ']]' +
config.script.advert
};
};
API.editWithRetry(
[config.xfd.subpagePath + 'Holding cell'],
null,
transform,
function() { self.track('edit', true); },
function(code, error, title) {
switch(code) {
case "noChangesMade":
self.addError([
'Did not find any changes to make to the holding cell'
]);
self.track('edit', false);
break;
default:
self.addApiError(code, error, [
'Could not add templates to holding cell'
]);
self.track('edit', false);
}
apiEditHoldingCell(newWikitext, holdCellSections[i]);
}
).fail( function(errortype, code, jqxhr) {
};
if ( errortype === "read" ) {
 
self.addApiError(code, jqxhr, 'Could not read contents of holding cell');
//get holding cell contents
self.setStatus('failed');
API.get( {
} // other errors handled above
action: 'query',
titles: config.xfd.subpagePath + 'होल्डिंग सेल',
prop: 'revisions',
rvprop: 'content',
indexpageids: 1,
rawcontinue: ''
} )
.done( processHoldingCellPage )
.fail( function(code, jqxhr) {
self.addApiError(code, jqxhr, 'होल्डिंग सेल के सामग्री ना पढ़ल जा सकल');
self.setStatus('failed');
} );
};
 
Task.prototype.doTask.deleteTalk = function(self) {
 
// Notify task is started
self.setStatus('started');
 
// Get talk pages
var talkTitles = self.discussion.getTalkTitles(self.pages);
if ( talkTitles.length === 0 ) {
self.addWarning('none found');
self.setStatus('skipped');
return;
}
self.setupTracking('del', talkTitles.length);
 
// Delete with the api
apiDeletePagevar apiDeleteTalkPage = function(pageTitletalkTitle, isRetry) {
API.postWithToken( 'csrf', {
action: 'delete',
title: pageTitletalkTitle,
reason: '[[WP:CSD#G8|G8]]: हटावलTalk पन्नाpage केof वार्ताdeleted पन्ना।page.' + config.script.advert
} )
.done( function() {
Line 4,244 ⟶ 4,955:
} )
.fail( function(code, jqxhr) {
if (!isRetry) {
return apiDeleteTalkPage(talkTitle, true);
}
self.track('del', false);
self.addApiError(code, jqxhr, [
'Could not delete page ',
'पन्ना हटावल ना जा सकल ',
extraJs.makeLink(pageTitletalkTitle)
]);
} );
};
//For each talk page, check that it exists and is eligible for a G8 speedy, then delete it
talkTitles.forEach( function(talkTitle) {
var subjectPage = self.discussion.getPageByTalkTitle(talkTitle);
var isUserTalkBasePage = ( subjectPage.getNamespaceId() === 2 ) && ( !talkTitle.includes('/') );
 
if ( !subjectPage.getTalkPage().exists() ) {
// Get talk pages
self.addWarning([
var talkTitles = self.discussion.getTalkTitles(self.pages);
extraJs.makeLink(talkTitle),
if ( talkTitles.length === 0 ) {
' skipped: does not exist (may have already been deleted by others)'
self.addWarning('एकहू ना मिलल');
]);
self.setStatus('छोड़ल गइल');
self.track('del', false);
} else {
return;
// get talk page redirect status from api
self.setupTracking('del', talkTitles.length);
//For each talk page, check that it exists, then delete it
for ( var i=0; i < talkTitles.length; i++ ) {
var subjectPage = self.discussion.getPageByTalkTitle(talkTitles[i]);
if ( subjectPage.talkExists ) {
apiDeletePage(talkTitles[i]);
} else {
self.addWarning([
extraJs.makeLink(talkTitles[i]),
' छोड़ल गइल: मौजूद नइखे (केहू पहिलहीं हटा दिहले होखी)'
]);
self.track('del', false);
}
}
if ( isUserTalkBasePage ) {
}
self.addWarning([
extraJs.makeLink(talkTitle),
' skipped: base user talk page (not eligible for G8 speedy deletion)'
]);
self.track('del', false);
return;
}
 
// Delete with the api
apiDeleteTalkPage(talkTitle);
});
};
 
Line 4,281 ⟶ 4,997:
// Notify task is started
self.setStatus('started');
// Get talk pages
var talkTitles = self.discussion.getTalkTitles(self.pages);
if ( talkTitles.length === 0 ) {
self.addWarning('none found');
self.setStatus('skipped');
return;
}
// get talk page redirect status from api
self.setupTracking('tag', talkTitles.length);
 
var apiTagPage = function(pageTitle, isRetry) {
API.postWithToken( 'csrf', {
action: 'edit',
title: pageTitle,
prependtext: '{{Db-talk}}\n',
summary: '[[WP:G8|G8]] तुरंतSpeedy हटावेdeletion के नामांकनnomination, कारणper [[:' +
self.discussion.getNomPageLink() + ']]' + config.script.advert
} )
Line 4,294 ⟶ 5,020:
} )
.fail( function(code, jqxhr) {
if (!isRetry) {
return apiTagPage(pageTitle, true);
}
self.track('tag', false);
self.addApiError(code, jqxhr, [
'Could not tag page ',
'पन्ना हटावल ना जा सकल ',
extraJs.makeLink(pageTitle),
' for speedy deletion'
]);
} );
};
//For each talk page, check that it exists, then tag it
// Get talk pages
var talkTitles = self.discussion.getTalkTitlesforEach(self.pagesfunction(talkTitle); {
var subjectPage = self.discussion.getPageByTalkTitle(talkTitle);
if ( talkTitles.length === 0 ) {
if ( !subjectPage.getTalkPage().exists() ) {
self.addWarning('एकहू ना मिलल');
self.addWarning([
self.setStatus('छोड़ल गइल');
extraJs.makeLink(talkTitle),
} else {
' skipped: does not exist (may have already been deleted by others)'
// get talk page redirect status from api
]);
self.setupTracking('tag', talkTitles.length);
self.track('tag', false);
//For each talk page, check that it exists, then tag it
for ( var i=0; i < talkTitles.length; i++ ) {
var subjectPage = self.discussion.getPageByTalkTitle(talkTitles[i]);
if ( subjectPage.talkExists ) {
apiTagPage(talkTitles[i]);
} else {
self.addWarning([
extraJs.makeLink(talkTitles[i]),
' छोड़ल गइल: मौजूद नइखे (केहू अउरी हटा दिहले होखी)'
]);
self.track('tag', false);
}
}
apiTagPage(talkTitle);
}
});
};
 
Line 4,339 ⟶ 5,058:
// Delete redirect with the api
var apiDeleteRedir = function(_ipageTitle, pageTitleisRetry) {
API.postWithToken( 'csrf', {
action: 'delete',
title: pageTitle,
reason: 'अनुप्रेषणDelete हटावल जायredirect: [[' + self.discussion.getNomPageLink() + ']] समापन केclosed कारणas ' +
self.inputData.getResult() + config.script.advert
} )
Line 4,350 ⟶ 5,069:
} )
.fail( function(code, jqxhr) {
if (!isRetry) {
return apiDeleteRedir(pageTitle, true);
}
self.track('delRedir', false);
self.addApiError(code, jqxhr, [
'Could not delete redirect ',
'अनुप्रेषण हटावल ना जा सकल ',
extraJs.makeLink(pageTitle)
]);
Line 4,359 ⟶ 5,081:
 
// Delete redirect talkpage with the api
var apiDeleteRedirTalk = function(_italkpageid, talkpageidisRetry) {
API.postWithToken( 'csrf', {
action: 'delete',
pageid: talkpageid,
reason: '[[WP:CSD#G8|G8]]: हटावलTalk पन्नाpage केof वार्ताdeleted पन्ना।page.' + config.script.advert
} )
.done( function() {
Line 4,369 ⟶ 5,091:
} )
.fail( function(code, jqxhr) {
if (!isRetry) {
return apiDeleteRedirTalk(talkpageid, true);
}
self.track('delRedirTalk', false);
self.addApiError(code, jqxhr, [
'Could not delete ',
$('<a>').attr({
'href':'https://bhen.wikipedia.org/wiki/?curid='+talkpageid,
'target':'_blank'
}).text('अनुप्रेषणredirect वार्ताtalk पन्नाpage <'+talkpageid+'>')
]);
} );
Line 4,390 ⟶ 5,115:
);
// Delete each redirect
redirectTitles.forEach(function(redirectTitle) {
$.each(redirectTitles, apiDeleteRedir);
apiDeleteRedir(redirectTitle);
});
// Check if talk pages were found
Line 4,405 ⟶ 5,132:
);
// Delete each talk page
redirectTalkPageIds.forEach(function(redirectTalkId) {
$.each(redirectTalkPageIds, apiDeleteRedirTalk);
apiDeleteRedirTalk(redirectTalkId);
};
});
// If user cancelled
var doSkipRedirects = function() {
self.addWarning('प्रयोगकर्ता द्वारा कैंसिल');
self.setStatus('छोड़ल गइल');
};
Line 4,417 ⟶ 5,140:
if ( !result.query || !result.query.pages ) {
// No results
self.addWarning('एकहूnone ना मिललfound');
self.setStatus('छोड़ल गइलskipped');
return;
}
Line 4,434 ⟶ 5,157:
// Check if redirects were found
if ( redirectTitles.length === 0 ) {
self.addWarning('एकहूnone ना मिललfound');
self.setStatus('छोड़ल गइलskipped');
return;
}
Line 4,441 ⟶ 5,164:
// Warn if there will be mass action, allow user to cancel
if ( redirectTitles.length >= 10 ) {
 
var massActWarningCallback = function(action) {
var processAction = function(action) {
if ( action === 'accept' ) {
doDeleteRedirects();
} else if ( action === 'show' ) {
extraJs.multiButtonConfirm({
title: 'चेतावनीWarning',
message: 'कईMass कार्रवाईaction होखेto वालाbe बाpeformed: हटावल जाईdelete '+ redirectTitles.length +
' अनुप्रेषणredirects:<ul><li>[[' + redirectTitles.join(']]</li><li>[[') + ']]</li></ul>',
actions: [
{ label:'कैंसिलCancel', flags:'safe' },
{ label:'अनुप्रेषणDelete हटाईंredirects', action:'accept', flags:'progressive' }
],
massActWarningCallback,size: 'medium'
})
{'verbose': true, 'unescape': true, 'wikilinks':true}
.then(processAction);
} else {
doSkipRedirectsself.addWarning('Cancelled by user');
self.setStatus('skipped');
}
};
 
extraJs.multiButtonConfirm({
title: 'चेतावनीWarning',
message: 'कईMass संख्याaction मेंto कार्रवाईbe peformed: हटावल जायdelete '+ redirectTitles.length + ' अनुप्रेषण।redirects.',
actions: [
{ label:'कैंसिलCancel', flags:'safe' },
{ label:'अनुप्रेषणView देखींredirects...', action:'show' },
{ label:'अनुप्रेषणDelete हटाईंredirects', action:'accept', flags:'progressive' }
],
size: 'medium'
massActWarningCallback
});
.then(processAction);
} else {
doDeleteRedirects();
Line 4,489 ⟶ 5,215:
.done( processRedirects )
.fail( function(code, jqxhr) {
self.addApiError(code, jqxhr, 'अनुप्रेषणCould हासिलnot नाobtain कइल जा सकलredirects');
self.setStatus('failed');
} );
Line 4,504 ⟶ 5,230:
var pageTitles = self.discussion.getPageTitles(self.pages);
var redirectTitles = [];
// Ignore the following titles, and any of their subpages
var ignoreTitles = [
var ignoreTitleBases = [
'Template:WPUnited States Article alerts',
'Template:Article alerts columns',
'Template:ArticleDid alertsyou columns/docknow nominations'
];
var getBase = function(title) {
return title.split('/')[0];
};
var blresults = [];
var iuresults = [];
//convert results (arrays of objects) to titles (arrays of strings), removing duplicates
var flattenToTitles = function(arrresults) {
return arrresults.reduce(
function(aflatTitles, bresult) {
if ( bresult.redirlinks ) {
if ( $!redirectTitles.inArrayincludes(bresult.title, redirectTitles) === -1 ) {
redirectTitles.push(bresult.title);
}
return aflatTitles.concat(
bresult.redirlinks.reduce(
function(aaflatRedirLinks, bbredirLink) {
if (
$flatTitles.inArrayincludes(bbredirLink.title, a) !== -1 ||
$pageTitles.inArrayincludes(bbredirLink.title, pageTitles) !== -1 ||
$ignoreTitleBases.inArrayincludes(bbgetBase(redirLink.title, ignoreTitles)!== -1)
) {
return aaflatRedirLinks;
} else {
return aaflatRedirLinks.concat(bbredirLink.title);
}
},
Line 4,537 ⟶ 5,267:
);
} else if (
bresult.redirect === '' ||
$flatTitles.inArrayincludes(bresult.title, a) !== -1 ||
$pageTitles.inArrayincludes(bresult.title, pageTitles) !== -1 ||
ignoreTitleBases.includes(getBase(result.title))
$.inArray(b.title, ignoreTitles)!== -1
) {
return aflatTitles;
} else {
return aflatTitles.concat(bresult.title);
}
},
Line 4,551 ⟶ 5,281:
};
 
/**
var apiEditPage = function(pageTitle, newWikitext) {
* @param {String} pageTitle
API.postWithToken( 'csrf', {
* @param {String} wikitext
action: 'edit',
* @returns {Promise(String)} updated wikitext, with any list items either removed or unlinked
title: pageTitle,
*/
text: newWikitext,
var checkListItems = function(pageTitle, wikitext, isMajorEdit) {
summary: 'कड़ी हटावल जा रहल बा' +
(( config.xfd.type === 'ffd' ) ? ' / फाइल इस्तेमाल' : '' ) +
': [[' + self.discussion.getNomPageLink() + ']] बंद कइल गइल ' +
self.inputData.getResult() + config.script.advert,
minor: 1,
nocreate: 1
} )
.done( function() {
self.track('unlink', true);
} )
.fail( function(code, jqxhr) {
self.track('unlink', false);
self.addApiError(code, jqxhr, [
'Could not remove backlinks from ',
extraJs.makeLink(pageTitle)
]);
} );
};
var checkListItems = function(pageTitle, wikitext) {
// Find lines marked with {{subst:void}}, and the preceding section heading (if any)
var toReview = /^{{subst:void}}(.*)$/m.exec(wikitext);
if ( !toReview ) {
// None found, sono makechanges the editneeded
return $.Deferred().resolve(wikitext, !!isMajorEdit).promise();
apiEditPage(pageTitle, wikitext);
} else {
// Find the preceding heading, if any
var precendingText = wikitext.split('{{subst:void}}')[0];
var allHeadings = precendingText.match(/^=+.+?=+$/gm);
var heading = ( !allHeadings ) ? null : allHeadings[allHeadings.length - 1].replace(/(^=* *| *=*$)/g, '');
// Prompt user
extraJs.multiButtonConfirm(
'कड़ीतोड़ के कारवाई के लिस्ट देखीं',
'[[' + pageTitle +
( ( heading ) ? '#' +
mw.util.wikiUrlencode(
heading.replace(/\[\[([^\|\]]*?)\|([^\]]*?)\]\]/, '$2')
.replace(/\[\[([^\|\]]*?)\]\]/, '$1')
) + ']]' : ']]' ) +
': ' +
'<pre>' + toReview[1] + '</pre>',
[{ label:'आइटम रखीं', action:'keep' }, { label:'आइटम हटाईं', action:'remove'}],
function(action) {
if ( action === 'keep' ) {
// Remove the void from the start of the line
wikitext = wikitext.replace(/^{{subst:void}}/m, '');
} else {
// Remove the whole line
wikitext = wikitext.replace(/^{{subst:void}}.*\n?/m, '');
}
// Iterate, in case there is more to be reviewed
checkListItems(pageTitle, wikitext);
},
{ verbose:true, unescape:true, wikilinks:true }
);
}
// Find the preceding heading, if any
var precendingText = wikitext.split('{{subst:void}}')[0];
var allHeadings = precendingText.match(/^=+.+?=+$/gm);
var heading = ( !allHeadings ) ? null : allHeadings[allHeadings.length - 1]
.replace(/(^=* *| *=*$)/g, '')
.replace(/\[\[([^\|\]]*?)\|([^\]]*?)\]\]/, '$2')
.replace(/\[\[([^\|\]]*?)\]\]/, '$1');
// Prompt user
return multiButtonConfirm({
title: 'Review unlinked list item',
message: '<p>A backlink has been removed from the following list item:</p>' +
'<strong>List:</strong> [[' + pageTitle +
( heading
? '#' + mw.util.wikiUrlencode(heading) + '|' + pageTitle + '#' + heading + ']]'
: ']]'
) +
'<pre>' + toReview[1] + '</pre>' +
'<p>Please check if the item matches the list\'s [[WP:LISTCRITERIA|selection criteria]]'+
' before deciding to keep or remove the item from the list.</p>',
actions: [
{ label:'Keep item', action:'keep', icon:'articleCheck', flags:'progressive' },
{ label:'Keep and request citation', action:'keep-cite', icon:'flag' },
{ label:'Remove item', action:'remove', icon:'trash', flags:'destructive'}
],
size: 'large'
})
.then(function(action) {
if ( action === 'keep' ) {
// Remove the void from the start of the line
wikitext = wikitext.replace(/^{{subst:void}}/m, '');
} else if ( action === 'keep-cite' ) {
// Remove the void from the start of the line, add citation needed at the end
wikitext = wikitext.replace(/^{{subst:void}}(.*)(\n?)/m, '$1{{subst:Citation needed}}$2');
} else {
// Remove the whole line, mark as a major edit
wikitext = wikitext.replace(/^{{subst:void}}.*\n?/m, '');
isMajorEdit = true;
}
// Iterate, in case there is more to be reviewed
return checkListItems(pageTitle, wikitext, isMajorEdit);
});
};
var processUnlinkPages = function(result) {
// Function to transform a simplified API page object into edit parameters for API.editWithRetry
if ( !result.query || !result.query.pages ) {
var confirmationPromises = [$.Deferred()]; // Each transformation must wait for the previous one to finish dipslaying confirmation prompts
// No results
var transform = function(page) {
self.addApiError('result.query.pages not found', null, 'पन्ना के सामग्री ना पढ़ल जा सकल; '+
var previousPromise = confirmationPromises[confirmationPromises.length-1];
'इहाँ आवे वाली कड़ी ना तूरल जा सकल');
var thisConfirmationPromise = $.Deferred();
console.log('[XFDcloser] API error: result.query.pages not found... result =');
confirmationPromises.push(thisConfirmationPromise);
console.log(result);
return previousPromise.then(function(){
self.setStatus('failed');
var oldWikitext = page.content;
return;
}
// For each page, pass the wikitext through the unlink function
$.each(result.query.pages, function(_i, page) {
var oldWikitext = page.revisions[0]['*'];
var newWikitext = extraJs.unlink(
oldWikitext,
Line 4,633 ⟶ 5,351:
!!page.categories
);
if ( oldWikitext !=== newWikitext ) {
thisConfirmationPromise.resolve();
checkListItems(page.title, newWikitext);
return $.Deferred().reject('skippedNoLinks');
} else {
self.addWarning(['छोड़ल गइल ',
extraJs.makeLink(page.title),
' (कौनों डाइरेक्ट कड़ी ना)'
]);
self.track('unlink', false);
}
var checkListItemsPromise = checkListItems(page.title, newWikitext);
checkListItemsPromise.then(thisConfirmationPromise.resolve);
return checkListItemsPromise.then(function(updatedWikitext, isMajorEdit) {
var req = {
text: newWikitext,
summary: 'Removing link(s)' +
( isMajorEdit ? ' / list item(s)' : '') +
(( config.xfd.type === 'ffd' ) ? ' / file usage(s)' : '' ) +
': [[' + self.discussion.getNomPageLink() + ']] closed as ' +
self.inputData.getResult() + config.script.advert,
nocreate: 1
};
if ( !isMajorEdit ) {
req.minor = 1;
}
return req;
});
});
};
 
var apiReadFail = function(code, jqxhr) {
self.addApiError(code, jqxhr, 'Could not read contents of pages; '+
'could not remove backlinks');
self.setStatus('failed');
};
Line 4,664 ⟶ 5,388:
// Check if, after flattening, there are still backlinks or image uses
if ( blresults.length === 0 && iuresults.length === 0 ) {
self.addWarning('एकहूnone ना मिललfound');
self.setStatus('skipped');
return;
}
 
// Ask user for confirmation
Line 4,684 ⟶ 5,409:
'<p>Use with caution, after reviewing the pages listed below. '+
'Note that the use of high speed, high volume editing software (such as this tool and '+
'Twinkle\'s unlink tool) is subject to the Bot policy\'s [[WP:ASSISTED|Assisted editing guidelines]] '+
'(WP:ASSISTED)</p><hr>';
var list = '<ul>';
if ( blresults.length !== 0 ) {
Line 4,695 ⟶ 5,420:
list += '<ul>';
extraJs.multiButtonConfirm({
title: heading,
message: para + list,
actions: [
{ label: 'कैंसिलCancel', flags: 'safe' },
{ label: 'कड़ीRemove तूरींbacklinks', action: 'accept', flags: 'progressive' }
],
size: 'medium'
function(action) {
})
if ( action ) {
.then(function(action) {
var unlinkTitles = iuresults.concat(blresults);
if ( action ) {
self.setupTracking('unlink', unlinkTitles.length);
var unlinkTitles = iuresults.concat(blresults);
// get wikitext of titles, check if disambig - in lots of 50 (max for Api)
for self.setupTracking(var'unlink', ii=0; ii<unlinkTitles.length); ii+=50) {
self.showTrackingProgress = 'unlink';
API.get( {
// Define api callbacks outside of loop
action: 'query',
var onSuccess = function() { self.track('unlink', true); };
titles: unlinkTitles.slice(ii, ii+49).join('|'),
var onFailure = function(code, error, title) {
prop: 'categories|revisions',
switch(code) {
clcategories: 'श्रेणी:सगरी बहुअर्थी पन्ना',
rvprop:case 'content',"skippedNoLinks":
indexpageids:self.addWarning(['Skipped 1',
} extraJs.makeLink(title),
.done ' (no processUnlinkPagesdirect links)'
.fail( apiReadFail ]);
self.track('unlink', false);
break;
default:
self.addApiError(code, error, [
'Could not remove backlinks from ',
extraJs.makeLink(title)
]);
self.track('unlink', false);
}
} else {;
var onReadFail = function(errortype, code, jqxhr) {
self.addWarning('प्रयोगकर्ता द्वारा कैंसिल');
if ( errortype === "read" ) {
self.setStatus('skipped');
self.addApiError(code, jqxhr, 'Could not read contents of pages; could not remove backlinks');
self.setStatus('failed');
} // other errors handled above
};
// loop over unlinkTitles in lots of 50 (max for Api)
for (var ii=0; ii<unlinkTitles.length; ii+=50) {
API.editWithRetry(
unlinkTitles.slice(ii, ii+49).join('|'),
{
prop: 'categories|revisions',
clcategories: 'Category:All disambiguation pages',
},
transform,
onSuccess,
onFailure
).fail( onReadFail );
}
confirmationPromises[0].resolve();
},
} else {
{'verbose': true, 'unescape': true, 'wikilinks': true}
self.addWarning('Cancelled by user');
);
self.setStatus('skipped');
}
});
};
 
Line 4,760 ⟶ 5,512:
.done( processBacklinks )
.fail( function(code, jqxhr) {
self.addApiError(code, jqxhr, 'कड़ीCould नाnot हासिलretrieve कइल जा सकलbacklinks');
self.setStatus('failed');
// Allow delete redirects task to begin
Line 4,810 ⟶ 5,562:
var pageTitles = self.discussion.getPageTitles(self.pages);
var deleteFirst = self.inputData.deleteFirst;
var softRedirect = self.inputData.result === 'सॉफ्टsoft अनुप्रेषणredirect';
var rcats = self.inputData.rcats;
var rcatshell = ( rcats ) ? "\n\n{{Rcat shell|\n" + rcats + "\n}}" : '';
if ( rcats ) {
rcatshell = "\n\n{{Rcat shell|\n" + rcats + "\n}}";
} else if ( rcats === '' ) {
rcatshell = '\n\n{{Rcat shell}}';
}
 
self.setupTracking('redir', pageTitles.length);
 
// Make a redirect
var apiMakeRedirect = function(pageTitle, isRetry) {
var newWikitext;
if ( softRedirectpageTitle.indexOf('Module:') === 0 ) {
var targetPage = self.inputData.getTargetLink(pageTitle, true);
if ( targetPage.indexOf('Module:') !== 0 ) {
self.track('redir', false);
self.addError([
'Could not redirect ',
extraJs.makeLink(pageTitle),
' because target (',
extraJs.makeLink(targetPage),
') is not a module'
], true);
return false;
}
newWikitext = 'return require( "' + targetPage + '" )';
} else if ( softRedirect ) {
newWikitext = '{{Soft redirect|' + self.inputData.getTargetLink(pageTitle, true) +
'}}' + rcatshell;
Line 4,835 ⟶ 5,596:
title: pageTitle,
text: newWikitext,
summary: '[[:' + self.discussion.getNomPageLink() + ']] बंदclosed कइल गइलas ' +
self.inputData.getResult() + config.script.advert
} )
Line 4,842 ⟶ 5,603:
} )
.fail( function(code, jqxhr) {
if (!isRetry) {
apiMakeRedirect(pageTitle, true);
}
self.track('redir', false);
self.addApiError(code, jqxhr, [
'Could not edit page ',
'पन्ना संपादित ना कइल जा सकल ',
extraJs.makeLink(pageTitle)
]);
Line 4,851 ⟶ 5,615:
 
// Delete before redirecting
var apiDelAndRedir = function(pageTitle, isRetry) {
API.postWithToken( 'csrf', {
action: 'delete',
Line 4,861 ⟶ 5,625:
} )
.fail( function(code, jqxhr) {
if (!isRetry) {
apiDelAndRedir(pageTitle, true);
}
self.track('redir', false);
self.addApiError(code, jqxhr, [
'Could not delete page ',
'पन्ना हटावल ना जा सकल ',
extraJs.makeLink(pageTitle)
]);
Line 4,891 ⟶ 5,658:
self.setupTracking('uncircle', targetTitles.length);
 
// Function to transform a simplified API page object into edit parameters for API.editWithRetry
// Edit with the Api
var apiEditPagetransform = function(pageTitle, newWikitextpage) {
var oldWikitext = page.content;
API.postWithToken( 'csrf', {
// Don't remove selflinks
action: 'edit',
var unlinkPageTitles = pageTitles.filter(function(t){
title: pageTitle,
return t !== page.title;
});
var newWikitext = extraJs.unlink(oldWikitext, unlinkPageTitles);
// Check if any changes need to be made; if redirect target is a nominated page, remove
// nomination template and adjust edit summary
if ( newWikitext === oldWikitext ) {
// No links to unlink
return $.Deferred().reject("noCircularRedirects");
}
if ( $.inArray(page.title, pageTitles) !== -1 ) {
// Target is one of the nominated pages - also try to remove nom template if present
try {
newWikitext = config.xfd.removeNomTemplate(newWikitext);
} catch(e){
// Warning if multiple nom templates found
return $.Deferred().reject("multipleNomTemplates", e);
}
}
return {
text: newWikitext,
summary: 'चक्रUnlinking केcircular रूप में अनुप्रेषण हटावल जात बाredirects: [[:' + self.discussion.getNomPageLink() +
']] बंदclosed कइल गइलas ' + self.inputData.getResult() + config.script.advert
} );
.done( function() {
self.track('uncircle', true);
} )
.fail( function(code, jqxhr) {
self.track('uncircle', false);
self.addApiError(code, jqxhr, [
'पन्ना पर संपादन ना कइल जा सकल ',
extraJs.makeLink(pageTitle)
]);
} );
};
API.editWithRetry(
processTargets = function (result) {
targetTitles,
$.each(result.query.pages, function(_i, page) {
null,
console.log('_i = ' + _i + '\npage.title = ' + page.title);
transform,
var oldWikitext = page.revisions[ 0 ][ '*' ];
function() { self.track('edit', true); },
// Don't remove selflinks
function(code, error, title) {
var unlinkPageTitles = pageTitles.filter(function(t){
switch(code) {
return t !== page.title;
case "noCircularRedirects":
});
self.addWarning('none found');
var newWikitext = extraJs.unlink(oldWikitext, unlinkPageTitles);
self.track('uncircle', false);
break;
// Check if any changes need to be made; if redirect target is a nominated page, remove
case "multipleNomTemplates":
// nomination template and adjust edit summary
self.addError([
if ( newWikitext === oldWikitext ) {
error.message + ' ',
// No links to unlink
extraJs.makeLink(title)
self.addWarning('none found');
]);
self.track('uncircle', false);
break;
} else if ( $.inArray(page.title, pageTitles) !== -1 ) {
default:
// Target is one of the nominated pages - also remove nom template if present
self.addApiError(code, error, [
newWikitext = newWikitext.replace(config.xfd.regex.nomTemplate, '');
'Could not edit page ',
apiEditPage(page.title, newWikitext);
extraJs.makeLink(title)
} else {
]);
apiEditPage(page.title, newWikitext);
self.track('uncircle', false);
}
});
).fail( function(errortype, code, jqxhr) {
};
if ( errortype === "read" ) {
self.addApiError(code, jqxhr,
// Get the wikitext of each target
'Could not read contents of redirect target' + ( targetTitles.length > 1 ) ? 's' : '');
API.get( {
self.setStatus('failed');
action: 'query',
} // other errors handled above
titles: targetTitles.join('|'),
prop: 'revisions',
rvprop: 'content',
indexpageids: 1,
rawcontinue: ''
} )
.done( processTargets )
.fail( function(code, jqxhr) {
self.track('redir', false);
self.addApiError(code, jqxhr,
'अनुप्रेषण टारगेट' + ( targetTitles.length > 1 ) ? 'सभ' : '' + ' के सामग्री पढ़ल ना जा सकल');
} );
};
Line 4,964 ⟶ 5,733:
 
var now = new Date();
var today = now.getUTCFullYear() + ' ' + config.mw.monthNames[now.getUTCMonth()] +
' ' + now.getUTCDate();
var todaysLogpage = config.xfd.path + today;
Line 4,971 ⟶ 5,740:
if ( config.xfd.type !== 'mfd' ) {
self.discussion.taskManager.getTaskByName('updateNewLogPage').setDescription([
'Adding to ',
'जोड़ल जात बा, ',
extraJs.makeLink(todaysLogpage, "आजtoday's केlog लॉग पन्ना परpage")
]);
}
var processAfdLogpagesquery = function(result) {
action: 'query',
titles: self.discussion.nomPage,
// Get wikitext
prop: 'revisions',
var newlogtext = '';
indexpageids: 1,
var oldlogtext = '';
rawcontinue: 1,
var ids = result.query.pageids;
rvprop: 'content|timestamp',
rvslots: 'main',
// Check how many log pages were found
rvsection: self.discussion.sectionNumber,
if ( ids.length === 1 ) {
curtimestamp: 1
// Abort if only one log page found
};
self.discussion.taskManager.abortTasks(
if ( config.xfd.type === 'afd' ) {
'चर्चा पहिलहीं आ के लॉग पन्ना पर ट्रांसक्लूड कइल जा चुकल बा'
$.extend(query, {
);
list: 'embeddedin',
return;
eititle: self.discussion.nomPage,
}
einamespace: config.xfd.ns_logpages,
eifilterredir: 'nonredirects',
// Identify log pages
eilimit: 500
if ( result.query.pages[ ids[0] ].title === todaysLogpage ) {
});
// ids[0] is the new log page
// Need to fetch whole page, in order to check if afd is already closed
newlogtext = result.query.pages[ ids[0] ].revisions[0]['*'];
delete query.rvsection;
oldlogtext = result.query.pages[ ids[1] ].revisions[0]['*'];
}
} else {
// ids[0] is the old log page
API.get( query )
newlogtext = result.query.pages[ ids[1] ].revisions[0]['*'];
.then( function (result) {
oldlogtext = result.query.pages[ ids[0] ].revisions[0]['*'];
}
// Abort if already relisted
var t = mw.RegExp.escape(self.discussion.nomPage);
var oldPatt = new RegExp('<!-- ?\\{\\{' + t + '\\}\\} ?-->', 'i');
var newPatt = new RegExp('\\{\\{' + t + '\\}\\}', 'i');
if ( oldPatt.test(oldlogtext) || newPatt.test(newlogtext) ) {
self.discussion.taskManager.abortTasks('चर्चा के पहिलहीं रीलिस्ट कइल जा चुकल बा');
return;
}
// Updated new log wikitext:
var newlogreg = new RegExp('<!-- Add new entries to the TOP of the following list -->','i');
self.discussion.taskManager.relistInfo.newLogWikitext = newlogtext.replace(
newlogreg,
'<!-- Add new entries to the TOP of the following list -->\n{{' +
self.discussion.nomPage + '}}<!--Relisted-->'
);
// Updated old log wikitext:
var oldlogreg = new RegExp("(\\{\\{" + t + "\\}\\})", 'i' );
self.discussion.taskManager.relistInfo.oldlogTransclusion = oldlogreg.test(oldlogtext);
self.discussion.taskManager.relistInfo.oldLogWikitext = oldlogtext.replace(
oldlogreg, '<!-- $1 -->');
// Ready to proceed to next tasks
self.track('done', true);
};
 
// TFD, RRD
var processTodaysLogpage = function(result) {
var _id = result.query.pageids;
var _contents = result.query.pages[ _id ].revisions[ 0 ][ '*' ];
var _h4 = _contents.match('====');
if ( _h4 ) {
// there is at least 1 level 4 heading on page - can prepend to section #2
self.discussion.taskManager.relistInfo.newLogEditType = 'prependtext';
self.discussion.taskManager.relistInfo.newLogSection = 2;
} else {
// there are no level 4 headings on page - can append to section #1
self.discussion.taskManager.relistInfo.newLogEditType = 'appendtext';
self.discussion.taskManager.relistInfo.newLogSection = 1;
 
}
// Ready to proceed to next tasks
self.track('done', true);
};
 
var processNomPage = function (result) {
// Discussion wikitext
var id = result.query.pageids;
var oldWikitext = result.query.pages[ id ].revisions[0].slots.main['*'];
var heading = oldWikitext.slice(0, oldWikitext.indexOf('\n'));
 
// Abort if discussion is already closed
if ( oldWikitext.indexOf('xfd-closed') !== -1 ) {
self.discussion.taskManager.abortTasks('चर्चाdiscussion बंदhas कइलbeen जा चुकल बाclosed');
return;
}
Line 5,063 ⟶ 5,783:
// Relist template
var relists = oldWikitext
.match(/\[\[Wikipedia:Deletion process#Relisting discussions\|Relisted\]\]/g);
.match(/\[\[विकिपीडिया:हटावे के प्रक्रिया#दोबारा लिस्टिंग\|रीलिस्ट कइल गइल\]\]/g);
var relistTemplate = '\n{{subst:Relist|1=' + self.inputData.getRelistComment() +
'|2=' + (( relists ) ? relists.length + 1 : 1) + '}}\n';
Line 5,076 ⟶ 5,796:
// Update link to log page
newWikitext = newWikitext.replace(
/\[\[विकिपीडियाWikipedia:हटावे खातिर लेख\/लॉगLog\/\d{4} \w+ \d{1,2}#/,
'[[' + todaysLogpage + '#'
);
Line 5,083 ⟶ 5,803:
// Discussion on old log page gets closed
var xfdCloseTop = config.xfd.wikitext.closeTop
.replace(/__RESULT__/, 'रीलिस्ट कइल गइलrelisted')
.replace(/__TO_TARGET__/, ' on [[' + todaysLogpage + '#' +
self.discussion.sectionHeader + '|' + today + ']] टारगेट')
.replace(/__RATIONALE__/, '.')
.replace(/__SIG__/, config.user.sig);
Line 5,092 ⟶ 5,812:
if ( !self.discussion.isBasicMode() ) {
pagesList = self.discussion.pages.reduce(function(list, page) {
var namespaceParam = ( page.getNamespaceId() === 828 ) ? '|module=Module' : '';
return list + config.xfd.wikitext.pagelinks.replace('__PAGE__', page.getMain());
return list + config.xfd.wikitext.pagelinks.replace('__PAGE__', page.getMain() + namespaceParam);
}, '');
}
Line 5,122 ⟶ 5,843:
oldLogWikitext = topWikitext + '\n{{subst:rfd relisted|page=' + today +
'|' + self.discussion.sectionHeader + '}}';
} else if ( config.xfd.type === 'cfd' ) {
oldLogWikitext = '====' + self.discussion.sectionHeader + '====' +
'\n{{subst:cfd relisted|' + self.discussion.sectionHeader + '}}';
}
Line 5,128 ⟶ 5,852:
'today': today,
'newWikitext': newWikitext,
'oldLogWikitext': oldLogWikitext,
'nomPageTimestamps': {
start: result.curtimestamp,
base: result.query.pages[ id ].revisions[0].timestamp
}
};
Line 5,139 ⟶ 5,867:
// Abort if none found
if ( eiLogpages.length === 0 ) {
self.addError('पुरनकाOld लॉगlog पन्नाpage नाnot मिललfound');
self.discussion.taskManager.abortTasks('');
return;
Line 5,147 ⟶ 5,875:
for (var i = 1; i < eiLogpages.length; i++) {
self.addWarning([
'Note: transcluded on additional log page: ',
'नोट: अतिरिक्त लॉग पन्ना प ट्रांसक्लूड: ',
extraJs.makeLink(
eiLogpages[i].title,
Line 5,159 ⟶ 5,887:
// Abort if old log page is actually today's logpage
if ( oldLogpage.title === todaysLogpage ) {
self.addError('Already transcluded to today\'s log page');
self.addError('पहिलहीं आज के लॉग पन्ना पर ट्रांसक्लूड बा');
self.discussion.taskManager.abortTasks('');
return;
Line 5,166 ⟶ 5,894:
self.discussion.taskManager.getTaskByName('updateOldLogPage').setDescription([
'Removing from ',
extraJs.makeLink(oldLogpage.title, 'पुरनकाold लॉगlog पन्नाpage')
]);
// Store old log title
Line 5,176 ⟶ 5,904:
titles: oldLogpage.title + '|' + todaysLogpage,
prop: 'revisions',
rvprop: 'content|timestamp',
rvslots: 'main',
indexpageids: 1,
rawcontinue: '',
"curtimestamp": 1
} )
.donethen( processAfdLogpages function(result) {
// Get wikitext
.fail( function(code, jqxhr) {
var newlogtext = '';
self.addApiError(code, jqxhr, 'लॉग पन्ना के सामग्री ना पढ़ल जा सकल');
var oldlogtext = '';
var ids = result.query.pageids;
// Check how many log pages were found
if ( ids.length === 1 ) {
// Abort if only one log page found
self.discussion.taskManager.abortTasks(
'discussion already transcluded to today\'s log page'
);
return;
}
var newLogBaseTimestamp, oldLogBaseTimestamp;
// Identify log pages
if ( result.query.pages[ ids[0] ].title === todaysLogpage ) {
// ids[0] is the new log page
newlogtext = result.query.pages[ ids[0] ].revisions[0].slots.main['*'];
newLogBaseTimestamp = result.query.pages[ ids[0] ].revisions[0].timestamp;
oldlogtext = result.query.pages[ ids[1] ].revisions[0].slots.main['*'];
oldLogBaseTimestamp = result.query.pages[ ids[1] ].revisions[0].timestamp;
} else {
// ids[0] is the old log page
newlogtext = result.query.pages[ ids[1] ].revisions[0].slots.main['*'];
newLogBaseTimestamp = result.query.pages[ ids[1] ].revisions[0].timestamp;
oldlogtext = result.query.pages[ ids[0] ].revisions[0].slots.main['*'];
oldLogBaseTimestamp = result.query.pages[ ids[0] ].revisions[0].timestamp;
}
// Abort if already relisted
var t = mw.util.escapeRegExp(self.discussion.nomPage);
var oldPatt = new RegExp('<!-- ?\\{\\{' + t + '\\}\\} ?-->', 'i');
var newPatt = new RegExp('\\{\\{' + t + '\\}\\}', 'i');
if ( oldPatt.test(oldlogtext) || newPatt.test(newlogtext) ) {
self.discussion.taskManager.abortTasks('discussion has been relisted already');
return;
}
// Updated new log wikitext:
var newlogreg = new RegExp('<!-- Add new entries to the TOP of the following list -->','i');
self.discussion.taskManager.relistInfo.newLogWikitext = newlogtext.replace(
newlogreg,
'<!-- Add new entries to the TOP of the following list -->\n{{' +
self.discussion.nomPage + '}}<!--Relisted-->'
);
self.discussion.taskManager.relistInfo.newLogTimestamps = {
start: result.curtimestamp,
base: newLogBaseTimestamp
};
// Updated old log wikitext:
var oldlogreg = new RegExp("(\\{\\{" + t + "\\}\\})", 'i' );
self.discussion.taskManager.relistInfo.oldlogTransclusion = oldlogreg.test(oldlogtext);
self.discussion.taskManager.relistInfo.oldLogWikitext = oldlogtext.replace(
oldlogreg, '<!-- $1 -->');
self.discussion.taskManager.relistInfo.oldLogTimestamps = {
start: result.curtimestamp,
base: oldLogBaseTimestamp
};
// Ready to proceed to next tasks
self.track('done', true);
}, function(code, jqxhr) {
self.addApiError(code, jqxhr, 'Could not read contents of log pages');
self.discussion.taskManager.abortTasks('');
} );
} else if ( config.xfd.type === 'tfd' || config.xfd.type === 'rfd' || config.xfd.type === 'cfd' ) {
//New discussions on top of log page, so need to check out current log page wikitext
API.get( {
Line 5,192 ⟶ 5,984:
titles: todaysLogpage,
prop: 'revisions',
rvprop: 'content|timestamp',
rvslots: 'main',
indexpageids: 1,
rawcontinue: ''
} )
.then(function(response) {
.done( processTodaysLogpage )
var page = pageFromResponse(response);
.fail( function(code, jqxhr) {
var logWikitext = page.revisions[ 0 ].slots.main['*'];
var h4_match = /====\s*(.*?)\s*====/.exec(logWikitext);
var h4 = h4_match && h4_match[1];
if ( h4 ) {
// there is at least 1 level 4 heading on page - can edit section #2
self.discussion.taskManager.relistInfo.newLogSection = 2;
if ( h4.toUpperCase() === "NEW NOMINATIONS" ) {
self.discussion.taskManager.relistInfo.newLogEditType = 'appendtext';
} else {
self.discussion.taskManager.relistInfo.newLogEditType = 'prependtext';
}
} else {
// there are no level 4 headings on page - can append to section #1
self.discussion.taskManager.relistInfo.newLogEditType = 'appendtext';
self.discussion.taskManager.relistInfo.newLogSection = 1;
 
}
self.discussion.taskManager.relistInfo.newLogTimestamps = {
start: response.curtimestamp,
base: page.revisions[ 0 ].timestamp
};
// Ready to proceed to next tasks
self.track('done', true);
}, function(code, jqxhr) {
self.addApiError(code, jqxhr, [
'Could not read contents of ',
extraJs.makeLink(todaysLogpage, "'के लॉग पन्ना के सामग्री ना पढ़ल जा सकल")
extraJs.makeLink(todaysLogpage, "today's log page")
]);
self.discussion.taskManager.abortTasks('');
Line 5,209 ⟶ 6,027:
self.track('done', true);
}
}, function(code, jqxhr) {
};
var query = {
action: 'query',
titles: self.discussion.nomPage,
prop: 'revisions',
indexpageids: 1,
rawcontinue: 1,
rvprop: 'content',
rvsection: self.discussion.sectionNumber
};
if ( config.xfd.type === 'afd' ) {
$.extend(query, {
list: 'embeddedin',
eititle: self.discussion.nomPage,
einamespace: config.xfd.ns_logpages,
eifilterredir: 'nonredirects',
eilimit: 500
});
// Need to fetch whole page, in order to check if afd is already closed
delete query.rvsection;
}
API.get( query )
.done( processNomPage )
.fail( function(code, jqxhr) {
self.addApiError(code, jqxhr,
[ 'एहCould not read contents of page ',
extraJs.makeLink(self.discussion.nomPage),
'; could not relist discussion' ]
' पन्ना के सामग्री ना पढ़ल जा सकल; चर्चा रीलिस्ट ना कइल जा सकी' ]
);
self.discussion.taskManager.abortTasks('');
Line 5,257 ⟶ 6,051:
title: self.discussion.nomPage,
text: relistInfo.newWikitext,
summary: 'चर्च रीलिस्ट कइल जात बाRelisting discussion' + config.script.advert,
// Protect against errors and conflicts
assert: 'user',
basetimestamp: relistInfo.nomPageTimestamps.base,
starttimestamp: relistInfo.nomPageTimestamps.start
};
if ( config.xfd.type === 'mfd' ) {
Line 5,269 ⟶ 6,067:
.fail( function(code, jqxhr) {
self.track('edit', false);
self.addApiError(code, jqxhr, 'एहCould not edit ' + config.xfd.type.toUpperCase() +
' discussion');
' चर्चा में संपादन ना कइल जा सकल');
} );
};
Line 5,287 ⟶ 6,085:
title: ( config.xfd.type === 'afd' ) ? relistInfo.oldlogtitle : self.discussion.nomPage,
text: relistInfo.oldLogWikitext,
summary: (( config.xfd.type === 'afd' ) ? 'Relisting [[:' + self.discussion.nomPage +
']] रीलिस्ट कइल जात बा' : '/* ' + self.discussion.sectionHeader + ' */ Relisted on [[:' +
config.xfd.path + relistInfo.today + '#' + self.discussion.sectionHeader +
'|' + relistInfo.today + ']] पर रीलिस्ट कइल गइल') + config.script.advert
};
if (relistInfo.oldLogTimestamps) {
params.basetimestamp = relistInfo.oldLogTimestamps.base;
params.starttimestamp = relistInfo.oldLogTimestamps.start;
}
if ( config.xfd.type === 'afd' ) {
Line 5,297 ⟶ 6,100:
if ( !relistInfo.oldlogTransclusion ) {
self.track('edit', false);
self.addError('Transclusion not found on old log page; could not be commented out');
self.addError('पुरनका लॉग पन्ना पर ट्रांसक्लूजन ना मिलल; ओकरा के कमेंट आउट ना कइल जा सकत बा');
return;
}
Line 5,310 ⟶ 6,113:
.fail( function(code, jqxhr) {
self.track('edit', false);
self.addApiError(code, jqxhr, 'पुरनकाCould not edit old ' + config.xfd.type.toUpperCase() +
' log page');
' लॉग पन्ना संपादित ना कइल जा सकल');
} );
};
Line 5,330 ⟶ 6,133:
action: 'edit',
title: config.xfd.path + relistInfo.today,
summary: 'रीलिस्ट कइल जाताRelisting ' + (( config.xfd.type === 'afd' ) ? '[[:' + self.discussion.nomPage +
']]' : '"' + self.discussion.sectionHeader + '"') + config.script.advert
};
Line 5,338 ⟶ 6,141:
params[relistInfo.newLogEditType] = relistInfo.newWikitext;
}
if (relistInfo.newLogTimestamps) {
params.basetimestamp = relistInfo.newLogTimestamps.base;
params.starttimestamp = relistInfo.newLogTimestamps.start;
}
if ( /(tfd|rfd|cfd)/.test(config.xfd.type) ) {
params.section = relistInfo.newLogSection;
}
Line 5,349 ⟶ 6,156:
.fail( function(code, jqxhr) {
self.track('edit', false);
self.addApiError(code, jqxhr, 'आजCould केnot edit today\'s ' + config.xfd.type.toUpperCase() +
' log page');
' लॉग पन्ना ना संपादित कइल जा सकल');
} );
};
Line 5,360 ⟶ 6,167:
 
var relistInfo = self.discussion.taskManager.relistInfo;
//var todayParts = relistInfo.today.split(' ');
var pageTitles = self.discussion.getPageTitles(null, {'moduledocs':true});
self.setupTracking('edit', pageTitles.length);
// Function to transform a simplified API page object into edit parameters for API.editWithRetry
var apiEditPage = function(pageTitle, updatedWikitext) {
var transform = function(page) {
API.postWithToken( 'csrf', {
// Check there's a corresponding nominated page
action: 'edit',
var pageObj = self.discussion.getPageByTitle(page.title, {'moduledocs': true});
title: pageTitle,
if ( !pageObj ) {
return $.Deferred().reject("unexpectedTitle");
}
// Check corresponding page exists
if ( page.missing ) {
return $.Deferred().reject("doesNotExist");
}
var originalWikitext = page.content;
var updatedWikitext;
try {
updatedWikitext = config.xfd.updateNomTemplateAfterRelist(
originalWikitext,
relistInfo.today,
self.discussion.sectionHeader
);
} catch(e){
return $.Deferred().reject("couldNotUpdate", e);
}
var noChangesToMake = updatedWikitext === originalWikitext;
if ( noChangesToMake ) {
return $.Deferred().reject("nominationTemplateNotFound");
}
return {
text: updatedWikitext,
summary: 'अपडेट कइल जाताUpdating ' + config.xfd.type.toUpperCase() +
' टेम्पलेटtemplate: चर्चाdiscussion रीलिस्टwas भइल रहलrelisted' + config.script.advert
} );
.done( function() {
self.track('edit', true);
} )
.fail( function(code, jqxhr) {
self.track('edit', false);
self.addApiError(code, jqxhr, [
'पन्ना पर संपादन ना कइल जा सकल ',
extraJs.makeLink(pageTitle)
]);
} );
};
API.editWithRetry(
var processPages = function(result) {
pageTitles,
//Get old wikitext, or make error if page doesn't exist, or if page is in wrong namespace
null,
var ids = result.query.pageids;
transform,
for (var i = 0; i < ids.length; i++) {
function() { self.track('edit', true); },
var pageTitle = result.query.pages[ ids[i] ].title;
function(code, error, title) {
// Check there's a corresponding nominated page
switch(code) {
var pageObj = self.discussion.getPageByTitle(pageTitle);
case "unexpectedTitle":
if ( !pageObj ) {
self.addError([
'API query result included unexpected title ',
'एपीआइ क्वैरी के रिजल्ट में अनचिन्हुआ टाइटिल सामिल बा ',
extraJs.makeLink(pageTitletitle),
'; this talk page will not be edited'
'; ई पन्ना संपादित ना कइल जाई'
]);
self.track('edit', false);
continue break;
case "doesNotExist":
self.addError([
extraJs.makeLink(title),
' does not exist, and will not be edited'
]);
self.track('processed', false);
break;
case "couldNotUpdate":
self.addError([
'Could not update ',
extraJs.makeLink(title),
': ',
error.message
]);
self.track('edit', false);
break;
case "nominationTemplateNotFound":
self.addWarning([
'Nomination template not found on page ',
extraJs.makeLink(title)
]);
self.track('edit', false);
break;
default:
self.addApiError(code, error, [
'Could not edit page ',
extraJs.makeLink(title)
]);
self.track('edit', false);
}
// Check that page exists
if ( parseInt(ids[i]) < 0 ) {
self.addError([
extraJs.makeLink(pageTitle),
' मौजूद नइखे आ संपादन ना कइल जाई'
]);
self.track('edit', false);
continue;
}
// Update wikitext
var oldWikitext = result.query.pages[ ids[i] ].revisions[0]['*'];
var newWikitext = oldWikitext.replace(
config.xfd.regex.relistPattern,
config.xfd.wikitext.relistReplace.replace("__TODAY__", relistInfo.today)
);
// Skip if no changes made
if ( newWikitext === oldWikitext ) {
self.track('edit', false);
self.addWarning([
'छोड़ल गइल ',
extraJs.makeLink(pageTitle),
': नामांकन टेम्पलेट ना मिलल'
]);
continue;
}
// Make the edit
apiEditPage(pageTitle, newWikitext);
}
).fail( function(errortype, code, jqxhr) {
};
if ( errortype === "read" ) {
 
// self.addApiError(code, Getjqxhr, each'Could not read contents of nominated page's wikitext+
( pageTitles.length > 1 ) ? 's' : '');
new mw.Api().get( {
self.setStatus('failed');
action: 'query',
} // other errors handled above
titles: pageTitles.join('|'),
prop: 'revisions',
rvprop: 'content',
indexpageids: 1
} )
.done( processPages )
.fail( function(code, jqxhr) {
self.addApiError(code, jqxhr, 'नामांकित पन्ना के सामग्री ना पढ़ल जा सकल; नामांकित पन्ना' +
( pageTitles.length > 1 ) ? 'सभ' : '');
self.setStatus('failed');
} );
};
Line 5,454 ⟶ 6,271:
// Determine previous state from localStorage
try {
if ( !!window.localStorage.getItem('xfdc-closedHidden') ) {
this.isHidden = true;
} else {
Line 5,469 ⟶ 6,286:
this.isHidden = true;
try {
window.localStorage.setItem('xfdc-closedHidden', true);
} catch(e) {}
$('.xfd-closed, .tfd-closed, #XFDcloser-showhide-hide').hide();
Line 5,478 ⟶ 6,295:
this.isHidden = false;
try {
window.localStorage.setItem('xfdc-closedHidden', '');
} catch(e) {}
$('.xfd-closed, .tfd-closed, #XFDcloser-showhide-hide').show();
Line 5,491 ⟶ 6,308:
$('<a>')
.attr('id', 'XFDcloser-showhide-hide')
.text('Hide closed discussions')
.text('बंद चर्चा सभ लुकवाईं')
.toggle(!self.isHidden)
.on('click', self.hideClosed),
$('<a>')
.attr('id', 'XFDcloser-showhide-show')
.text('बंदShow चर्चाclosed सभ देखींdiscussions')
.toggle(self.isHidden)
.on('click', self.showClosed)
Line 5,517 ⟶ 6,334:
if ( d ) {
try {
if ( d.retrieveExtraInfoisBasicMode(); ) {
d.showLinks();
} else {
d.retrieveExtraInfo()
.then(
function() { d.showLinks(); },
function(failMessage) {
// set "basic" mode, show "basic" links with the failure message
d.pages = false;
d.showLinks(failMessage);
}
);
}
} catch(e) {
console.warn('[XFDcloser] Could not retrieve page info for ' + $(this).text() +
' [see error below]');
' खातिर पन्ना जानकारी ना हासिल कइल जा सकल [खराबी नीचे देखीं]');
console.warn(e);
}
Line 5,532 ⟶ 6,361:
 
/* ========== End of full file closure wrappers ================================================ */
});
});
/* </nowiki> */