From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.

// forked from [[user:MusikAnimal/userRightsManager.js]] for adding decline options (per [[User_talk:MusikAnimal#PERM]])



/* 

 To install, add: 

	importScript('User:SD0001/userRightsManager.js'); // [[User:SD0001/userRightsManager.js]]

 to your common.js page

*/



// jshint maxerr: 999



// <nowiki>

// Some UI code adapted from [[User:Mr. Stradivarius/gadgets/Draftify.js]]

(function() {

if (!/Wikipedia:Requests for permissions\//.test(document.title)) {

	return;

}



var permissionNames = {

	'Account creator': 'accountcreator',

	'Autopatrolled': 'autoreviewer',

	'Confirmed': 'confirmed',

	'Event coordinator': 'eventcoordinator',

	'Extended confirmed': 'extendedconfirmed',

	'File mover': 'filemover',

	'Mass message sender': 'massmessage-sender',

	'New page reviewer': 'patroller',

	'Page mover': 'extendedmover',

	'Pending changes reviewer': 'reviewer',

	'Rollback': 'rollbacker',

	'Template editor': 'templateeditor'

};



var templates = {

	'Account creator': 'Account creator granted',

	'Autopatrolled': 'Autopatrolledgiven',

	'AutoWikiBrowser': '',

	'Confirmed': '',

	'Event coordinator': 'Event coordinator granted',

	'Extended confirmed': '',

	'File mover': 'Filemovergiven',

	'Mass message sender': 'Mass message sender granted',

	'New page reviewer': 'New Page Reviewer granted',

	'Page mover': 'Page mover granted',

	'Pending changes reviewer': 'Pending changes reviewer granted',

	'Rollback': 'Rollback granted 3',

	'Template editor': 'Template editor granted'

};



var decline_templates = {

	'Account creator': 'permission declined notification|Account creator|Wikipedia Accountcreators.svg',

	'Autopatrolled': 'permission declined notification|Autopatrolled|Wikipedia Autopatrolled.svg',

	'AutoWikiBrowser': '',

	'Confirmed': '',

	'Event coordinator': 'permission declined notification|Event coordinator|Wikipedia Event coordinator.svg',

	'Extended confirmed': '',

	'File mover': 'permission declined notification|File mover|Wikipedia File mover.svg',

	'Mass message sender': 'permission declined notification|Mass message sender|Wikipedia mass messenger.svg',

	'New page reviewer': 'permission declined notification|New page reviewer|Wikipedia New page reviewer.svg',

	'Page mover': 'permission declined notification|Page mover|Wikipedia page mover.svg',

	'Pending changes reviewer': 'permission declined notification|Pending changes reviewer|Wikipedia Reviewer.svg',

	'Rollback': 'permission declined notification|Rollback|Wikipedia Rollbacker.svg',

	'Template editor': 'permission declined notification|Template editor|Wikipedia Template editor icon (1).svg'

};



var api,

	permission = mw.config.get('wgTitle').split('/').slice(-1)[0],

	revisionId = mw.config.get('wgRevisionId'),

	tagLine = ' (using [[User:MusikAnimal/userRightsManager|userRightsManager]])',

	permaLink, userName, dialog;



mw.loader.using(['oojs-ui', 'mediawiki.api', 'mediawiki.widgets.DateInputWidget'], function() {

	api = new mw.Api();

	$('.perm-assign-permissions a').on('click', function(e) {

		if (permission === 'AutoWikiBrowser') {return true;}

		e.preventDefault();

		userName = $(this).parents('.plainlinks').find('a').eq(0).text();

		showDialog();

	});

	$('.perm-assign-permissions').after(

		' (',

		$('<a>').html('<span style="color: #03B;"><b>decline</b></span>').attr('href', '#')

			.click(function(e) {

				e.preventDefault();

				userName = $(this).parents('.plainlinks').find('a').eq(0).text();

				showDeclineDialog();

			}),

		')'

	);

});



function showDialog() {

	var Dialog = function(config) {

		Dialog.super.call(this, config);

	};

	OO.inheritClass(Dialog, OO.ui.ProcessDialog);

	Dialog.static.name = 'user-rights-manager';

	Dialog.static.title = 'Grant ' + permission + ' to ' + userName;

	Dialog.static.actions = 

		{ action: 'submit', label: 'Submit', flags: 'primary', 'constructive' },

		{ label: 'Cancel', flags: 'safe' }

	];

	Dialog.prototype.getApiManager = function() {

		return this.apiManager;

	};

	Dialog.prototype.getBodyHeight = function() {

		return 208;

	};

	Dialog.prototype.initialize = function() {

		Dialog.super.prototype.initialize.call(this);

		this.editFieldset = new OO.ui.FieldsetLayout({

			classes: 'container'

		});

		this.editPanel = new OO.ui.PanelLayout({

			expanded: false

		});

		this.editPanel.$element.append(this.editFieldset.$element);

		this.rightsChangeSummaryInput = new OO.ui.TextInputWidget({

			value: 'Requested at [[WP:PERM]]'

		});

		this.expiryInput = new mw.widgets.DateInputWidget({

			$overlay: $('.oo-ui-window')

		});

		this.closingRemarksInput = new OO.ui.TextInputWidget({

			value: '{{done}} ~~~~'

		});

		this.watchTalkPageCheckbox = new OO.ui.CheckboxInputWidget({

			selected: false

		});

		var formElements = 

			new OO.ui.FieldLayout(this.rightsChangeSummaryInput, {

				label: 'Summary'

			}),

			new OO.ui.FieldLayout(this.expiryInput, {

				label: 'Expiry (optional)'

			}),

			new OO.ui.FieldLayout(this.closingRemarksInput, {

				label: 'Closing remarks'

			})

		];

		if (templatespermission]) {

			formElements.push(

				new OO.ui.FieldLayout(this.watchTalkPageCheckbox, {

					label: 'Watch user talk page'

				})

			);

		}

		this.editFieldset.addItems(formElements);

		this.submitPanel = new OO.ui.PanelLayout({

			$: this.$,

			expanded: false

		});

		this.submitFieldset = new OO.ui.FieldsetLayout({

			classes: 'container'

		});

		this.submitPanel.$element.append(this.submitFieldset.$element);

		this.changeRightsProgressLabel = new OO.ui.LabelWidget();

		this.changeRightsProgressField = new OO.ui.FieldLayout(this.changeRightsProgressLabel);

		this.markAsDoneProgressLabel = new OO.ui.LabelWidget();

		this.markAsDoneProgressField = new OO.ui.FieldLayout(this.markAsDoneProgressLabel);

		this.issueTemplateProgressLabel = new OO.ui.LabelWidget();

		this.issueTemplateProgressField = new OO.ui.FieldLayout(this.issueTemplateProgressLabel);

		this.stackLayout = new OO.ui.StackLayout({

			items: this.editPanel, this.submitPanel],

			padded: true

		});

		this.$body.append(this.stackLayout.$element);

		$('.mw-widget-dateInputWidget').css('width', '100%');

	};



	Dialog.prototype.onSubmit = function() {

		var self = this, promiseCount = templatespermission ? 3 : 2;



		self.actions.setAbilities({ submit: false });



		addPromise = function(field, promise) {

			self.pushPending();

			promise.done(function() {

				field.$field.append($('<span>')

					.text('Complete!')

					.prop('style', 'position:relative; top:0.5em; color: #009000; font-weight: bold')

				);

			}).fail(function(obj) {

				if (obj && obj.error && obj.error.info) {

					field.$field.append($('<span>')

						.text('Error: ' + obj.error.info)

						.prop('style', 'position:relative; top:0.5em; color: #cc0000; font-weight: bold')

					);

				} else {

					field.$field.append($('<span>')

						.text('An unknown error occurred.')

						.prop('style', 'position:relative; top:0.5em; color: #cc0000; font-weight: bold')

					);

				}

			}).always(function() {

				promiseCount--; // FIXME: maybe we could use a self.isPending() or something

				self.popPending();



				if (promiseCount === 0) {

					setTimeout(function() {

						location.reload(true);

					}, 1000);

				}

			});



			return promise;

		};



		self.markAsDoneProgressField.setLabel('Marking request as done...');

		self.submitFieldset.addItems([self.markAsDoneProgressField]);

		self.changeRightsProgressField.setLabel('Assigning rights...');

		self.submitFieldset.addItems([self.changeRightsProgressField]);



		if (templatespermission]) {

			self.issueTemplateProgressField.setLabel('Issuing template...');

			self.submitFieldset.addItems([self.issueTemplateProgressField]);

		}



		addPromise(

			self.markAsDoneProgressField,

			editPERMpage('done', '\n::' + this.closingRemarksInput.getValue())

		).then(function(data) {

			addPromise(

				self.changeRightsProgressField,

				assignPermission(

					this.rightsChangeSummaryInput.getValue(),

					data..newrevid,

					this.expiryInput.getValue()

				)

			).then(function() {

				// silently add user to MMS list

				if (permission === 'New page reviewer') {addToMMSList();}



				if (templatespermission]) {

					addPromise(

						self.issueTemplateProgressField,

						issueTemplate(this.watchTalkPageCheckbox.isSelected(), this.expiryInput.getValue())

					);

				}

			}.bind(this));

		}.bind(this));



		self.stackLayout.setItem(self.submitPanel);

	};



	Dialog.prototype.getActionProcess = function(action) {

		return Dialog.super.prototype.getActionProcess.call(this, action).next(function() {

				if ( action === 'submit' ) {

					return this.onSubmit();

				}

					return Dialog.super.prototype.getActionProcess.call( this, action );



			}, this);

	};



	dialog = new Dialog({

		size: 'medium'

	});



	var windowManager = new OO.ui.WindowManager();

	$('body').append(windowManager.$element);

	windowManager.addWindows([dialog]);

	windowManager.openWindow(dialog);

}



function showDeclineDialog() {

	var Dialog = function(config) {

		Dialog.super.call(this, config);

	};

	OO.inheritClass(Dialog, OO.ui.ProcessDialog);

	Dialog.static.name = 'user-rights-manager';

	Dialog.static.title = 'Decline ' + permission + ' to ' + userName;

	Dialog.static.actions = 

		{ action: 'submit', label: 'Submit', flags: 'primary', 'constructive' },

		{ label: 'Cancel', flags: 'safe' }

	];

	Dialog.prototype.getApiManager = function() {

		return this.apiManager;

	};

	Dialog.prototype.getBodyHeight = function() {

		return 208;

	};

	Dialog.prototype.initialize = function() {

		Dialog.super.prototype.initialize.call(this);

		this.editFieldset = new OO.ui.FieldsetLayout({

			classes: 'container'

		});

		this.editPanel = new OO.ui.PanelLayout({

			expanded: false

		});

		this.editPanel.$element.append(this.editFieldset.$element);



		this.closingRemarksInput = new OO.ui.TextInputWidget({

			value: '{{not done}} ~~~~'

		});

		this.notifyUserCheckbox = new OO.ui.CheckboxInputWidget({

			selected: true

		});

		this.watchTalkPageCheckbox = new OO.ui.CheckboxInputWidget({

			selected: false

		});

		var formElements = 

			new OO.ui.FieldLayout(this.closingRemarksInput, {

				label: 'Closing remarks'

			})

		];

		if (decline_templatespermission]) {

			formElements.push(

				new OO.ui.FieldLayout(this.notifyUserCheckbox, {

					label: 'Notify user on talk page'

				})

			);

			formElements.push(

				new OO.ui.FieldLayout(this.watchTalkPageCheckbox, {

					label: 'Watch user talk page'

				})

			);

		}

		this.editFieldset.addItems(formElements);

		this.submitPanel = new OO.ui.PanelLayout({

			$: this.$,

			expanded: false

		});

		this.submitFieldset = new OO.ui.FieldsetLayout({

			classes: 'container'

		});

		this.submitPanel.$element.append(this.submitFieldset.$element);



		this.markAsDoneProgressLabel = new OO.ui.LabelWidget();

		this.markAsDoneProgressField = new OO.ui.FieldLayout(this.markAsDoneProgressLabel);

		this.issueTemplateProgressLabel = new OO.ui.LabelWidget();

		this.issueTemplateProgressField = new OO.ui.FieldLayout(this.issueTemplateProgressLabel);

		this.stackLayout = new OO.ui.StackLayout({

			items: this.editPanel, this.submitPanel],

			padded: true

		});

		this.$body.append(this.stackLayout.$element);

	};



	Dialog.prototype.onSubmit = function() {

		var self = this, promiseCount = decline_templatespermission ? 2 : 1;



		self.actions.setAbilities({ submit: false });



		addPromise = function(field, promise) {

			self.pushPending();

			promise.done(function() {

				field.$field.append($('<span>')

					.text('Complete!')

					.prop('style', 'position:relative; top:0.5em; color: #009000; font-weight: bold')

				);

			}).fail(function(obj) {

				if (obj && obj.error && obj.error.info) {

					field.$field.append($('<span>')

						.text('Error: ' + obj.error.info)

						.prop('style', 'position:relative; top:0.5em; color: #cc0000; font-weight: bold')

					);

				} else {

					field.$field.append($('<span>')

						.text('An unknown error occurred.')

						.prop('style', 'position:relative; top:0.5em; color: #cc0000; font-weight: bold')

					);

				}

			}).always(function() {

				promiseCount--; // FIXME: maybe we could use a self.isPending() or something

				self.popPending();



				if (promiseCount === 0) {

					setTimeout(function() {

						location.reload(true);

					}, 1000);

				}

			});



			return promise;

		};



		self.markAsDoneProgressField.setLabel('Marking request as not done...');

		self.submitFieldset.addItems([self.markAsDoneProgressField]);

		// self.changeRightsProgressField.setLabel( 'Assigning rights...' );

		// self.submitFieldset.addItems( [self.changeRightsProgressField] );



		if (!!decline_templatespermission && this.notifyUserCheckbox.getValue()) {

			self.issueTemplateProgressField.setLabel('Issuing template...');

			self.submitFieldset.addItems([self.issueTemplateProgressField]);

		}



		addPromise(

			self.markAsDoneProgressField,

			editPERMpage('not done', '\n::' + this.closingRemarksInput.getValue())

		).then(function(data) {

			if (!!decline_templatespermission && this.notifyUserCheckbox.isSelected()) {

				addPromise(

					self.issueTemplateProgressField,

					issueDeclineTemplate(this.watchTalkPageCheckbox.isSelected(), data..newrevid)

				);

			}

		}.bind(this));



		self.stackLayout.setItem(self.submitPanel);

	};



	Dialog.prototype.getActionProcess = function(action) {

		return Dialog.super.prototype.getActionProcess.call(this, action).next(function() {

				if ( action === 'submit' ) {

					return this.onSubmit();

				}

					return Dialog.super.prototype.getActionProcess.call( this, action );



			}, this);

	};



	dialog = new Dialog({

		size: 'medium'

	});



	var windowManager = new OO.ui.WindowManager();

	$('body').append(windowManager.$element);

	windowManager.addWindows([dialog]);

	windowManager.openWindow(dialog);

}



function assignPermission(summary, revId, expiry) {

	permaLink = '[[Special:PermaLink/' + revId + '#User:' + userName + '|permalink]]';

	return api.postWithToken('userrights', {

		action: 'userrights',

		format: 'json',

		user: userName.replace(/ /g, '_'),

		add: permissionNamespermission],

		reason: '+' + permissionNamespermission + '; ' + summary + '; ' + permaLink + tagLine,

		expiry: expiry === '' ? 'infinity' : expiry

	});

}



// `status` is either "done" or "not done"

function editPERMpage(status, closingRemarks) {

	var sectionNode = document.getElementById('User:' + userName.replace(/"/g, '.22').replace(/ /g, '_')),

		sectionNumber = $(sectionNode).siblings('.mw-editsection').find("a:not('.mw-editsection-visualeditor')").prop('href').match(/section=(\d+)/)[1];

	return api.postWithToken('csrf', {

		format: 'json',

		action: 'edit',

		title: mw.config.get('wgPageName'),

		section: sectionNumber,

		summary: '/* User:' + userName + ' */ ' + status + tagLine,

		appendtext: closingRemarks

	});

}



function issueDeclineTemplate(watch, revId) {

	permaLink = '[[Special:PermaLink/' + revId + '#User:' + userName + '|permalink]]';

	var talkPage = 'User talk:' + userName.replace(/ /g, '_');

	return api.postWithToken('csrf', {

		format: 'json',

		action: 'edit',

		title: talkPage,

		section: 'new',

		summary: 'Your request for ' + permission + ' was declined per ' + permaLink + tagLine,

		text: '{{subst:' + decline_templatespermission + '}}',

		sectiontitle: 'Your request for ' + permission0].toLowerCase() + permission.slice(1) + ' right',

		watchlist: watch ? 'watch' : 'unwatch'

	});

}



function issueTemplate(watch, expiry) {

	var talkPage = 'User talk:' + userName.replace(/ /g, '_');

	return api.postWithToken('csrf', {

		format: 'json',

		action: 'edit',

		title: talkPage,

		section: 'new',

		summary: permission + ' granted per ' + permaLink + tagLine,

		text: '{{subst:' + templatespermission + (expiry === '' ? '' : '|expiry=' + expiry) + '}}',

		sectiontitle: permission + ' granted',

		watchlist: watch ? 'watch' : 'unwatch'

	});

}



function addToMMSList() {

	api.postWithToken('csrf', {

		format: 'json',

		action: 'editmassmessagelist',

		spamlist: 'Wikipedia:New pages patrol/Reviewers/Newsletter list',

		add: 'User talk:' + userName

	});

}

})();

// </nowiki>
From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.

// forked from [[user:MusikAnimal/userRightsManager.js]] for adding decline options (per [[User_talk:MusikAnimal#PERM]])



/* 

 To install, add: 

	importScript('User:SD0001/userRightsManager.js'); // [[User:SD0001/userRightsManager.js]]

 to your common.js page

*/



// jshint maxerr: 999



// <nowiki>

// Some UI code adapted from [[User:Mr. Stradivarius/gadgets/Draftify.js]]

(function() {

if (!/Wikipedia:Requests for permissions\//.test(document.title)) {

	return;

}



var permissionNames = {

	'Account creator': 'accountcreator',

	'Autopatrolled': 'autoreviewer',

	'Confirmed': 'confirmed',

	'Event coordinator': 'eventcoordinator',

	'Extended confirmed': 'extendedconfirmed',

	'File mover': 'filemover',

	'Mass message sender': 'massmessage-sender',

	'New page reviewer': 'patroller',

	'Page mover': 'extendedmover',

	'Pending changes reviewer': 'reviewer',

	'Rollback': 'rollbacker',

	'Template editor': 'templateeditor'

};



var templates = {

	'Account creator': 'Account creator granted',

	'Autopatrolled': 'Autopatrolledgiven',

	'AutoWikiBrowser': '',

	'Confirmed': '',

	'Event coordinator': 'Event coordinator granted',

	'Extended confirmed': '',

	'File mover': 'Filemovergiven',

	'Mass message sender': 'Mass message sender granted',

	'New page reviewer': 'New Page Reviewer granted',

	'Page mover': 'Page mover granted',

	'Pending changes reviewer': 'Pending changes reviewer granted',

	'Rollback': 'Rollback granted 3',

	'Template editor': 'Template editor granted'

};



var decline_templates = {

	'Account creator': 'permission declined notification|Account creator|Wikipedia Accountcreators.svg',

	'Autopatrolled': 'permission declined notification|Autopatrolled|Wikipedia Autopatrolled.svg',

	'AutoWikiBrowser': '',

	'Confirmed': '',

	'Event coordinator': 'permission declined notification|Event coordinator|Wikipedia Event coordinator.svg',

	'Extended confirmed': '',

	'File mover': 'permission declined notification|File mover|Wikipedia File mover.svg',

	'Mass message sender': 'permission declined notification|Mass message sender|Wikipedia mass messenger.svg',

	'New page reviewer': 'permission declined notification|New page reviewer|Wikipedia New page reviewer.svg',

	'Page mover': 'permission declined notification|Page mover|Wikipedia page mover.svg',

	'Pending changes reviewer': 'permission declined notification|Pending changes reviewer|Wikipedia Reviewer.svg',

	'Rollback': 'permission declined notification|Rollback|Wikipedia Rollbacker.svg',

	'Template editor': 'permission declined notification|Template editor|Wikipedia Template editor icon (1).svg'

};



var api,

	permission = mw.config.get('wgTitle').split('/').slice(-1)[0],

	revisionId = mw.config.get('wgRevisionId'),

	tagLine = ' (using [[User:MusikAnimal/userRightsManager|userRightsManager]])',

	permaLink, userName, dialog;



mw.loader.using(['oojs-ui', 'mediawiki.api', 'mediawiki.widgets.DateInputWidget'], function() {

	api = new mw.Api();

	$('.perm-assign-permissions a').on('click', function(e) {

		if (permission === 'AutoWikiBrowser') {return true;}

		e.preventDefault();

		userName = $(this).parents('.plainlinks').find('a').eq(0).text();

		showDialog();

	});

	$('.perm-assign-permissions').after(

		' (',

		$('<a>').html('<span style="color: #03B;"><b>decline</b></span>').attr('href', '#')

			.click(function(e) {

				e.preventDefault();

				userName = $(this).parents('.plainlinks').find('a').eq(0).text();

				showDeclineDialog();

			}),

		')'

	);

});



function showDialog() {

	var Dialog = function(config) {

		Dialog.super.call(this, config);

	};

	OO.inheritClass(Dialog, OO.ui.ProcessDialog);

	Dialog.static.name = 'user-rights-manager';

	Dialog.static.title = 'Grant ' + permission + ' to ' + userName;

	Dialog.static.actions = 

		{ action: 'submit', label: 'Submit', flags: 'primary', 'constructive' },

		{ label: 'Cancel', flags: 'safe' }

	];

	Dialog.prototype.getApiManager = function() {

		return this.apiManager;

	};

	Dialog.prototype.getBodyHeight = function() {

		return 208;

	};

	Dialog.prototype.initialize = function() {

		Dialog.super.prototype.initialize.call(this);

		this.editFieldset = new OO.ui.FieldsetLayout({

			classes: 'container'

		});

		this.editPanel = new OO.ui.PanelLayout({

			expanded: false

		});

		this.editPanel.$element.append(this.editFieldset.$element);

		this.rightsChangeSummaryInput = new OO.ui.TextInputWidget({

			value: 'Requested at [[WP:PERM]]'

		});

		this.expiryInput = new mw.widgets.DateInputWidget({

			$overlay: $('.oo-ui-window')

		});

		this.closingRemarksInput = new OO.ui.TextInputWidget({

			value: '{{done}} ~~~~'

		});

		this.watchTalkPageCheckbox = new OO.ui.CheckboxInputWidget({

			selected: false

		});

		var formElements = 

			new OO.ui.FieldLayout(this.rightsChangeSummaryInput, {

				label: 'Summary'

			}),

			new OO.ui.FieldLayout(this.expiryInput, {

				label: 'Expiry (optional)'

			}),

			new OO.ui.FieldLayout(this.closingRemarksInput, {

				label: 'Closing remarks'

			})

		];

		if (templatespermission]) {

			formElements.push(

				new OO.ui.FieldLayout(this.watchTalkPageCheckbox, {

					label: 'Watch user talk page'

				})

			);

		}

		this.editFieldset.addItems(formElements);

		this.submitPanel = new OO.ui.PanelLayout({

			$: this.$,

			expanded: false

		});

		this.submitFieldset = new OO.ui.FieldsetLayout({

			classes: 'container'

		});

		this.submitPanel.$element.append(this.submitFieldset.$element);

		this.changeRightsProgressLabel = new OO.ui.LabelWidget();

		this.changeRightsProgressField = new OO.ui.FieldLayout(this.changeRightsProgressLabel);

		this.markAsDoneProgressLabel = new OO.ui.LabelWidget();

		this.markAsDoneProgressField = new OO.ui.FieldLayout(this.markAsDoneProgressLabel);

		this.issueTemplateProgressLabel = new OO.ui.LabelWidget();

		this.issueTemplateProgressField = new OO.ui.FieldLayout(this.issueTemplateProgressLabel);

		this.stackLayout = new OO.ui.StackLayout({

			items: this.editPanel, this.submitPanel],

			padded: true

		});

		this.$body.append(this.stackLayout.$element);

		$('.mw-widget-dateInputWidget').css('width', '100%');

	};



	Dialog.prototype.onSubmit = function() {

		var self = this, promiseCount = templatespermission ? 3 : 2;



		self.actions.setAbilities({ submit: false });



		addPromise = function(field, promise) {

			self.pushPending();

			promise.done(function() {

				field.$field.append($('<span>')

					.text('Complete!')

					.prop('style', 'position:relative; top:0.5em; color: #009000; font-weight: bold')

				);

			}).fail(function(obj) {

				if (obj && obj.error && obj.error.info) {

					field.$field.append($('<span>')

						.text('Error: ' + obj.error.info)

						.prop('style', 'position:relative; top:0.5em; color: #cc0000; font-weight: bold')

					);

				} else {

					field.$field.append($('<span>')

						.text('An unknown error occurred.')

						.prop('style', 'position:relative; top:0.5em; color: #cc0000; font-weight: bold')

					);

				}

			}).always(function() {

				promiseCount--; // FIXME: maybe we could use a self.isPending() or something

				self.popPending();



				if (promiseCount === 0) {

					setTimeout(function() {

						location.reload(true);

					}, 1000);

				}

			});



			return promise;

		};



		self.markAsDoneProgressField.setLabel('Marking request as done...');

		self.submitFieldset.addItems([self.markAsDoneProgressField]);

		self.changeRightsProgressField.setLabel('Assigning rights...');

		self.submitFieldset.addItems([self.changeRightsProgressField]);



		if (templatespermission]) {

			self.issueTemplateProgressField.setLabel('Issuing template...');

			self.submitFieldset.addItems([self.issueTemplateProgressField]);

		}



		addPromise(

			self.markAsDoneProgressField,

			editPERMpage('done', '\n::' + this.closingRemarksInput.getValue())

		).then(function(data) {

			addPromise(

				self.changeRightsProgressField,

				assignPermission(

					this.rightsChangeSummaryInput.getValue(),

					data..newrevid,

					this.expiryInput.getValue()

				)

			).then(function() {

				// silently add user to MMS list

				if (permission === 'New page reviewer') {addToMMSList();}



				if (templatespermission]) {

					addPromise(

						self.issueTemplateProgressField,

						issueTemplate(this.watchTalkPageCheckbox.isSelected(), this.expiryInput.getValue())

					);

				}

			}.bind(this));

		}.bind(this));



		self.stackLayout.setItem(self.submitPanel);

	};



	Dialog.prototype.getActionProcess = function(action) {

		return Dialog.super.prototype.getActionProcess.call(this, action).next(function() {

				if ( action === 'submit' ) {

					return this.onSubmit();

				}

					return Dialog.super.prototype.getActionProcess.call( this, action );



			}, this);

	};



	dialog = new Dialog({

		size: 'medium'

	});



	var windowManager = new OO.ui.WindowManager();

	$('body').append(windowManager.$element);

	windowManager.addWindows([dialog]);

	windowManager.openWindow(dialog);

}



function showDeclineDialog() {

	var Dialog = function(config) {

		Dialog.super.call(this, config);

	};

	OO.inheritClass(Dialog, OO.ui.ProcessDialog);

	Dialog.static.name = 'user-rights-manager';

	Dialog.static.title = 'Decline ' + permission + ' to ' + userName;

	Dialog.static.actions = 

		{ action: 'submit', label: 'Submit', flags: 'primary', 'constructive' },

		{ label: 'Cancel', flags: 'safe' }

	];

	Dialog.prototype.getApiManager = function() {

		return this.apiManager;

	};

	Dialog.prototype.getBodyHeight = function() {

		return 208;

	};

	Dialog.prototype.initialize = function() {

		Dialog.super.prototype.initialize.call(this);

		this.editFieldset = new OO.ui.FieldsetLayout({

			classes: 'container'

		});

		this.editPanel = new OO.ui.PanelLayout({

			expanded: false

		});

		this.editPanel.$element.append(this.editFieldset.$element);



		this.closingRemarksInput = new OO.ui.TextInputWidget({

			value: '{{not done}} ~~~~'

		});

		this.notifyUserCheckbox = new OO.ui.CheckboxInputWidget({

			selected: true

		});

		this.watchTalkPageCheckbox = new OO.ui.CheckboxInputWidget({

			selected: false

		});

		var formElements = 

			new OO.ui.FieldLayout(this.closingRemarksInput, {

				label: 'Closing remarks'

			})

		];

		if (decline_templatespermission]) {

			formElements.push(

				new OO.ui.FieldLayout(this.notifyUserCheckbox, {

					label: 'Notify user on talk page'

				})

			);

			formElements.push(

				new OO.ui.FieldLayout(this.watchTalkPageCheckbox, {

					label: 'Watch user talk page'

				})

			);

		}

		this.editFieldset.addItems(formElements);

		this.submitPanel = new OO.ui.PanelLayout({

			$: this.$,

			expanded: false

		});

		this.submitFieldset = new OO.ui.FieldsetLayout({

			classes: 'container'

		});

		this.submitPanel.$element.append(this.submitFieldset.$element);



		this.markAsDoneProgressLabel = new OO.ui.LabelWidget();

		this.markAsDoneProgressField = new OO.ui.FieldLayout(this.markAsDoneProgressLabel);

		this.issueTemplateProgressLabel = new OO.ui.LabelWidget();

		this.issueTemplateProgressField = new OO.ui.FieldLayout(this.issueTemplateProgressLabel);

		this.stackLayout = new OO.ui.StackLayout({

			items: this.editPanel, this.submitPanel],

			padded: true

		});

		this.$body.append(this.stackLayout.$element);

	};



	Dialog.prototype.onSubmit = function() {

		var self = this, promiseCount = decline_templatespermission ? 2 : 1;



		self.actions.setAbilities({ submit: false });



		addPromise = function(field, promise) {

			self.pushPending();

			promise.done(function() {

				field.$field.append($('<span>')

					.text('Complete!')

					.prop('style', 'position:relative; top:0.5em; color: #009000; font-weight: bold')

				);

			}).fail(function(obj) {

				if (obj && obj.error && obj.error.info) {

					field.$field.append($('<span>')

						.text('Error: ' + obj.error.info)

						.prop('style', 'position:relative; top:0.5em; color: #cc0000; font-weight: bold')

					);

				} else {

					field.$field.append($('<span>')

						.text('An unknown error occurred.')

						.prop('style', 'position:relative; top:0.5em; color: #cc0000; font-weight: bold')

					);

				}

			}).always(function() {

				promiseCount--; // FIXME: maybe we could use a self.isPending() or something

				self.popPending();



				if (promiseCount === 0) {

					setTimeout(function() {

						location.reload(true);

					}, 1000);

				}

			});



			return promise;

		};



		self.markAsDoneProgressField.setLabel('Marking request as not done...');

		self.submitFieldset.addItems([self.markAsDoneProgressField]);

		// self.changeRightsProgressField.setLabel( 'Assigning rights...' );

		// self.submitFieldset.addItems( [self.changeRightsProgressField] );



		if (!!decline_templatespermission && this.notifyUserCheckbox.getValue()) {

			self.issueTemplateProgressField.setLabel('Issuing template...');

			self.submitFieldset.addItems([self.issueTemplateProgressField]);

		}



		addPromise(

			self.markAsDoneProgressField,

			editPERMpage('not done', '\n::' + this.closingRemarksInput.getValue())

		).then(function(data) {

			if (!!decline_templatespermission && this.notifyUserCheckbox.isSelected()) {

				addPromise(

					self.issueTemplateProgressField,

					issueDeclineTemplate(this.watchTalkPageCheckbox.isSelected(), data..newrevid)

				);

			}

		}.bind(this));



		self.stackLayout.setItem(self.submitPanel);

	};



	Dialog.prototype.getActionProcess = function(action) {

		return Dialog.super.prototype.getActionProcess.call(this, action).next(function() {

				if ( action === 'submit' ) {

					return this.onSubmit();

				}

					return Dialog.super.prototype.getActionProcess.call( this, action );



			}, this);

	};



	dialog = new Dialog({

		size: 'medium'

	});



	var windowManager = new OO.ui.WindowManager();

	$('body').append(windowManager.$element);

	windowManager.addWindows([dialog]);

	windowManager.openWindow(dialog);

}



function assignPermission(summary, revId, expiry) {

	permaLink = '[[Special:PermaLink/' + revId + '#User:' + userName + '|permalink]]';

	return api.postWithToken('userrights', {

		action: 'userrights',

		format: 'json',

		user: userName.replace(/ /g, '_'),

		add: permissionNamespermission],

		reason: '+' + permissionNamespermission + '; ' + summary + '; ' + permaLink + tagLine,

		expiry: expiry === '' ? 'infinity' : expiry

	});

}



// `status` is either "done" or "not done"

function editPERMpage(status, closingRemarks) {

	var sectionNode = document.getElementById('User:' + userName.replace(/"/g, '.22').replace(/ /g, '_')),

		sectionNumber = $(sectionNode).siblings('.mw-editsection').find("a:not('.mw-editsection-visualeditor')").prop('href').match(/section=(\d+)/)[1];

	return api.postWithToken('csrf', {

		format: 'json',

		action: 'edit',

		title: mw.config.get('wgPageName'),

		section: sectionNumber,

		summary: '/* User:' + userName + ' */ ' + status + tagLine,

		appendtext: closingRemarks

	});

}



function issueDeclineTemplate(watch, revId) {

	permaLink = '[[Special:PermaLink/' + revId + '#User:' + userName + '|permalink]]';

	var talkPage = 'User talk:' + userName.replace(/ /g, '_');

	return api.postWithToken('csrf', {

		format: 'json',

		action: 'edit',

		title: talkPage,

		section: 'new',

		summary: 'Your request for ' + permission + ' was declined per ' + permaLink + tagLine,

		text: '{{subst:' + decline_templatespermission + '}}',

		sectiontitle: 'Your request for ' + permission0].toLowerCase() + permission.slice(1) + ' right',

		watchlist: watch ? 'watch' : 'unwatch'

	});

}



function issueTemplate(watch, expiry) {

	var talkPage = 'User talk:' + userName.replace(/ /g, '_');

	return api.postWithToken('csrf', {

		format: 'json',

		action: 'edit',

		title: talkPage,

		section: 'new',

		summary: permission + ' granted per ' + permaLink + tagLine,

		text: '{{subst:' + templatespermission + (expiry === '' ? '' : '|expiry=' + expiry) + '}}',

		sectiontitle: permission + ' granted',

		watchlist: watch ? 'watch' : 'unwatch'

	});

}



function addToMMSList() {

	api.postWithToken('csrf', {

		format: 'json',

		action: 'editmassmessagelist',

		spamlist: 'Wikipedia:New pages patrol/Reviewers/Newsletter list',

		add: 'User talk:' + userName

	});

}

})();

// </nowiki>

Videos

Youtube | Vimeo | Bing

Websites

Google | Yahoo | Bing

Encyclopedia

Google | Yahoo | Bing

Facebook