மீடியாவிக்கி:Gadget-twinkledeprod.js
//&lt;nowiki&gt;
 
 
 (function($){
 
 
 /*
 ****************************************
 *** twinkledeprod.js: Batch deletion of expired PRODs (sysops only)
 ****************************************
 * Mode of invocation:     Tab (&quot;Deprod&quot;)
 * Active on:              Categories whose name starts with &quot;Category:Proposed deletion as of&quot;
 * Config directives in:   TwinkleConfig
 */
 
 Twinkle.deprod = function() {
 	if(
 		mw.config.get( 'wgNamespaceNumber' ) !== 14 ||
 		! Morebits.userIsInGroup( 'sysop' ) ||
 		!((/proposed_deletion/i).test(mw.config.get( 'wgPageName' )))
 	) {
 		return;
 	}
 	Twinkle.addPortletLink( Twinkle.deprod.callback, &quot;Deprod&quot;, &quot;tw-deprod&quot;, &quot;Delete prod pages found in this category&quot;);
 };
 
 var concerns = {};
 
 Twinkle.deprod.callback = function() {
 	var Window = new Morebits.simpleWindow( 800, 400 );
 	Window.setTitle( &quot;PROD cleaning&quot; );
 	Window.setScriptName( &quot;Twinkle&quot; );
 	Window.addFooterLink( &quot;Proposed deletion&quot;, &quot;WP:PROD&quot; );
 	Window.addFooterLink( &quot;Twinkle help&quot;, &quot;WP:TW/DOC#deprod&quot; );
 
 	var form = new Morebits.quickForm( callback_commit );
 
 	var statusdiv = document.createElement( 'div' );
 	statusdiv.style.padding = '15px';  // just so it doesn't look broken
 	Window.setContent(statusdiv);
 	Morebits.status.init(statusdiv);
 	Window.display();
 
 	var query = {
 		'action': 'query',
 		'generator': 'categorymembers',
 		'gcmtitle': mw.config.get( 'wgPageName' ),
 		'gcmlimit' : 5000, // the max for sysops
 		'prop': [ 'info', 'revisions' ],
 		'rvprop': [ 'content' ],
 		'inprop': [ 'protection' ]
 	};
 
 	var statelem = new Morebits.status(&quot;Grabbing list of pages&quot;);
 	var wikipedia_api = new Morebits.wiki.api( 'loading...', query, function( apiobj ) {
 		var $doc = $(apiobj.responseXML);
 		var $pages = $doc.find('page[ns!=&quot;6&quot;]');  // all non-files
 		var list = [];
 		var re = /\{\{Proposed deletion/;
 		$pages.each(function() {
 			var $page = $(this);
 			var title = $page.attr('title');
 			var content = $page.find('revisions rev').text();
 			var $editprot = $page.find('pr[type=&quot;edit&quot;][level=&quot;sysop&quot;]');
 			var isProtected = $editprot.length &gt; 0;
 
 			var metadata = [];
 			var res = re.exec(content);
 			if( res ) {
 				var parsed = Morebits.wikitext.template.parse( content, res.index );
 				concerns[title] = parsed.parameters.concern || '';
 				metadata.push(concerns[title]);
 			}
 			if (isProtected) {
 				metadata.push(&quot;fully protected&quot; +
 					($editprot.attr('expiry') === 'infinity' ? ' indefinitely' : (', expires ' + $editprot.attr('expiry'))));
 			}
 			list.push({
 				label: (metadata.length ? ('(' + metadata.join('; ') + ')') : ''),
 				value: title,
 				checked: concerns[title] !== '',
 				style: (isProtected ? 'color:red' : '')
 			});
 		});
 		apiobj.params.form.append({ type: 'header', label: 'Pages to delete' });
 		apiobj.params.form.append({
 			type: 'button',
 			label: &quot;Select All&quot;,
 			event: function(e) {
 				$(Morebits.quickForm.getElements(e.target.form, 'pages')).prop('checked', true);
 			}
 		});
 		apiobj.params.form.append({
 			type: 'button',
 			label: &quot;Deselect All&quot;,
 			event: function(e) {
 				$(Morebits.quickForm.getElements(e.target.form, 'pages')).prop('checked', false);
 			}
 		});
 		apiobj.params.form.append({
 			'type': 'checkbox',
 			'name': 'pages',
 			'list': list
 		});
 		apiobj.params.form.append({
 			'type': 'submit'
 		});
 
 		var rendered = apiobj.params.form.render();
 		apiobj.params.Window.setContent( rendered );
 		$(Morebits.quickForm.getElements(rendered, 'pages')).each(function(index, checkbox) {
 			var $checkbox = $(checkbox);
 			var link = Morebits.htmlNode(&quot;a&quot;, $checkbox.val());
 			link.setAttribute(&quot;class&quot;, &quot;deprod-page-link&quot;);
 			link.setAttribute(&quot;href&quot;, mw.util.getUrl($checkbox.val()));
 			link.setAttribute(&quot;target&quot;, &quot;_blank&quot;);
 			$checkbox.next().prepend([link, &quot; &quot;]);
 		});
 	}, statelem );
 
 	wikipedia_api.params = { form:form, Window:Window };
 	wikipedia_api.post();
 };
 
 var callback_commit = function(event) {
 	var pages = event.target.getChecked( 'pages' );
 	Morebits.status.init( event.target );
 
 	var batchOperation = new Morebits.batchOperation(&quot;Deleting articles&quot;);
 	batchOperation.setOption(&quot;chunkSize&quot;, Twinkle.getPref('proddeleteChunks'));
 	batchOperation.setOption(&quot;preserveIndividualStatusLines&quot;, true);
 	batchOperation.setPageList(pages);
 	batchOperation.run(function(pageName) {
 		var params = { page: pageName, reason: concerns[page] };
 
 		var query = {
 			'action': 'query',
 			'titles': pageName,
 			'prop': 'redirects',
 			'rdlimit': 5000  // 500 is max for normal users, 5000 for bots and sysops
 		};
 		var wikipedia_api = new Morebits.wiki.api( 'Grabbing redirects', query, callback_deleteRedirects );
 		wikipedia_api.params = params;
 		wikipedia_api.post();
 
 		query = {
 			'action': 'query',
 			'titles': 'Talk:' + pageName
 		};
 		wikipedia_api = new Morebits.wiki.api( 'Checking whether ' + pageName + ' has a talk page', query,
 			callback_deleteTalk );
 		wikipedia_api.params = params;
 		wikipedia_api.post();
 
 		var page = new Morebits.wiki.page(pageName, &quot;Deleting article &quot; + pageName);
 		page.setEditSummary(&quot;Expired [[WP:PROD|PROD]], concern was: &quot; + concerns[pageName] + Twinkle.getPref('deletionSummaryAd'));
 		page.suppressProtectWarning();
 		page.deletePage(batchOperation.workerSuccess, batchOperation.workerFailure);
 	});
 },
 callback_deleteTalk = function( apiobj ) {
 	var $doc = $(apiobj.responseXML);
 	var exists = $doc.find('page:not([missing])').length &gt; 0;
 
 	if( !exists ) {
 		// no talk page; forget about it
 		return;
 	}
 
 	var page = new Morebits.wiki.page('Talk:' + apiobj.params.page, &quot;Deleting talk page of article &quot; + apiobj.params.page);
 	page.setEditSummary(&quot;[[WP:CSD#G8|G8]]: [[Help:Talk page|Talk page]] of deleted page \&quot;&quot; + apiobj.params.page + &quot;\&quot;&quot; + Twinkle.getPref('deletionSummaryAd'));
 	page.deletePage();
 },
 callback_deleteRedirects = function( apiobj ) {
 	var $doc = $(apiobj.responseXML);
 	$doc.find(&quot;redirects rd&quot;).each(function(){
 		var title = $(this).attr('title');
 		var page = new Morebits.wiki.page(title, &quot;Deleting redirecting page &quot; + title);
 		page.setEditSummary(&quot;[[WP:CSD#G8|G8]]: Redirect to deleted page \&quot;&quot; + apiobj.params.page + &quot;\&quot;&quot; + Twinkle.getPref('deletionSummaryAd'));
 		page.deletePage();
 	});
 };
 
 })(jQuery);