User:Psl85/warnings/Warnings.js

/** ** AxUserMsg.js - Ajax/API based adding comments and templates to User-Talk-Pages ** written in 2011 by User:Rillke; little parts are from MediaWiki:AjaxQuickDelete.js by DieBuche and from the old MediaWiki:Gadget-UserMessages.js ** bootstrap-code at MediaWiki:Gadget-UserMessages.js (which severed as idea for writing this script), help at Help:Gadget-UserMessages ** //

// Invoke automated jsHint-validation on save: A feature on Wikimedia Commons. // Interested? See commons:MediaWiki:JSValidator.js.

/*global $:false, mw:false, jsMsgAppend:false */ /*jshint curly:false, bitwise:false, laxbreak:true*/

(function { 'use strict';

if (window.AxUserMsg) return;

function ClsUPC($userInputField, $outputField, stCallBack, callingObject, CBValidChange) { // User Presence Check this.$userInputField = $userInputField; this.$outputField = $outputField; this.callingObject = callingObject; this.stCallBack = stCallBack; this.CBValidChange = CBValidChange; this.pendingCalls = 0; this.pendingSetTimeouts = 0; this.oldValue = ''; this.userNameExists = 2; var o = this; $userInputField.keyup( function (event) { 		var tmpUNE = o.userNameExists;		if ( o.isValidIP($(this).val) ) {			o.setToIP(tmpUNE);		} else {			o.execApiCall(false, $(this).val);		}	}); $userInputField.on('input', function { 		$userInputField.keyup;	}); $userInputField.on('selected', function { 		$userInputField.keyup;	}); }

ClsUPC.prototype.isValidIP = function (username) { if ( mw.util.isIPv4Address(username) ) return true; //IP v.4 return mw.util.isIPv6Address(username); //IP v.6 };

ClsUPC.prototype.setToIP = function (tmpUNE) { var o = this; o.userNameExists = -1; if ('function' === typeof(o.CBValidChange) && tmpUNE !== o.userNameExists ) { o.$outputField.attr('src', o.callingObject.umImgUserIsIP); o.$outputField.attr('alt', 'IP'); o.oldValue = o.callingObject.umCleanFileAndUser(o.$userInputField.val); o.CBValidChange(o, o.callingObject); } };

ClsUPC.prototype.execApiCall = function (isTimeout, val) { if (isTimeout) this.pendingSetTimeouts--; if (this.oldValue !== this.callingObject.umCleanFileAndUser(val)) { if (this.pendingCalls > 0) { if (!this.pendingSetTimeouts) { this.pendingSetTimeouts++; var o = this; setTimeout( function { 					o.execApiCall(true, o.$userInputField.val);				}, 1000); // do not use the old value, use the current instead }			return; }		var User = this.oldValue = this.callingObject.umCleanFileAndUser(val); var query = { action: 'query', list: 'allusers', aufrom: User, auto: User };		this.callingObject.umCurrentUserQuery = this; this.pendingCalls++; this.callingObject.doAPICall(query, this.stCallBack); } }; ClsUPC.prototype.evalAPICall = function(result) { this.pendingCalls--; var uifval = this.$userInputField.val; if (this.oldValue !== this.callingObject.umCleanFileAndUser(uifval)) { // Don't do anything if user updated the field in-between return; }	if (this.isValidIP(uifval)) { return; }	if ('object' === typeof(result.query) && 'object' === typeof(result.query.allusers)) { var tmpUNE = this.userNameExists; if (!result.query.allusers.length) { this.$outputField.attr('src', this.callingObject.umImgUserNotExists); this.$outputField.attr('alt', '!! invalid !!'); this.userNameExists = false; } else { if (this.callingObject.umCleanFileAndUser(this.$userInputField.val) === result.query.allusers[0].name) { this.$outputField.attr('src', this.callingObject.umImgUserExists); this.$outputField.attr('alt', 'OK'); this.userNameExists = true; } else { if (!this.pendingSetTimeouts) { // Only overwrite if there is nothing pending this.$outputField.attr('src', this.callingObject.umImgUserUndefined); this.$outputField.attr('alt', '?'); this.userNameExists = 2; }			}		}		if ('function' === typeof(this.CBValidChange) && tmpUNE !== this.userNameExists) this.CBValidChange(this, this.callingObject); } };

var umsg = window.AxUserMsg = { umInstall: function { if (!$('#t-AjaxUserMessage').length) { var _this = this; var $LODLinkNode = $('#t-AjaxUserMessageLOD'); var $Href = $LODLinkNode.length ? $LODLinkNode.eq(0) : $(mw.util.addPortletLink('p-tb', '#', "Notify this user", 't-AjaxUserMessage', 'Click here to launch user messages')); $Href.click(function(e) {				e.preventDefault;				_this.fireImmediately = false;				_this.umNotifyUser;			}); }		window.AxUserMsgPreSelect = (window.AxUserMsgPreSelect || this.umTemplate.length - 1); // default last msg },

umInstallOldLinks: function { // written for Herby, who needs this for working on Commons var _this = this; $.each(this.umTemplate, function(id, ti) {			// Create portlet link			var portletLink = mw.util.addPortletLink( 'p-tb', '#' + id, ti[1], 't-gadgetUserMessage' + id, ti[2]);			// Bind click handler			$(portletLink).click( function( e ) { e.preventDefault; window.AxUserMsgPreSelect = $(this).find('a').attr('href').split('#')[1]; if (window.AxUserMsgFireAsYouClick) { var umType = _this.umTemplate[window.AxUserMsgPreSelect][3]; if (!(umType & _this.umFlagUQ) && !(umType & _this.umFlagReq)) _this.fireImmediately = true; else { _this.fireImmediately = false; }				}				_this.umNotifyUser; });		});	},

umNotifyUser: function { var css = 'a.new {color: #BA0000 !important;}'; mw.util.addCSS(css); this.umUser = ''; this.editToken = ''; this.umDlgPresent = false; this.umExecuting = false; this.umPendingParser = 0; this.umPendingParserTimeouts = 0; this.umParserTimerID = 0; this.umDelay = (window.AxUserMsgDelay || 100); this.umUserCache = {}; this.umFileCache = {}; this.umParserCache = {}; this.focusOwner = ''; this.umObtainEditToken; this.umUser = mw.libs.commons.guessUser; this.umDlg; },	umFillSelect: function (caller, o) { var userstate = caller.userNameExists; $.each(o.umTemplate, function(id, currentTag) {			if ( !$('#umOpt' + id, o.$tagSelect).length ) { // check wether to add				if ( (-1 === userstate && !(currentTag[3] & o.umFlagUM)) || (true === userstate && !(currentTag[3] & o.umFlagIP)) ) {					o.$tagSelect.append( '' + mw.html.escape(currentTag[1] + ' - ' + currentTag[2]) + ' ' );					return;				}			} else { // check wether to remove				if ( (-1 === userstate && (currentTag[3] & o.umFlagUM)) || (true === userstate && (currentTag[3] & o.umFlagIP)) ) {					$('#umOpt' + id, o.$tagSelect).remove;					return;				}			}		}); if (-1 === userstate) { if (window.AxUserMsgPreSelectIP) { o.$tagSelect.val(window.AxUserMsgPreSelectIP); } } else { if (window.AxUserMsgPreSelect) { o.$tagSelect.val(window.AxUserMsgPreSelect); } }		o.umValidateInput(o); o.$tagSelect.change; },	umDlg: function { var _this = this, dlgButtons = {}; dlgButtons[this.i18n.submitButtonLabel] = function { try { if (_this.umIsValid) _this.umNotifyUserExecute; } catch (ex) { _this.fail(ex); }		};		dlgButtons[this.i18n.cancelButtonLabel] = function { $(this).dialog("close"); };		this.dlg = $(' ').html(' ').dialog({			modal: true,			closeOnEscape: true,			position: [Math.round(($(window).width - Math.min($(window).width, 850)) / 2), 						Math.round(($(window).height - Math.min($(window).height, 800)) / 2)],			title: 'User Messages-Script in Beta-Mode. '				+ 'Report bugs and ideas. '				+ 'Learn how to customize this gadget.',			height: Math.min($(window).height, 800),			width: Math.min($(window).width, 850),			buttons: dlgButtons,			close: function {				$(this).dialog("destroy");				$(this).remove;				_this.umDlgPresent = false;			},			open: function {				var $dlg = $(this),					$buttons = $dlg.parent.find('.ui-dialog-buttonpane button'),					$submitButton = $buttons.eq(0).specialButton('✔ proceed'), $cancelButton = $buttons.eq(1).specialButton('❌ cancel'); $dlg.parents('.ui-dialog').css({position:'fixed', top:Math.round(($(window).height - Math.min($(window).height, 800)) / 2) + 'px'}); }		});		this.umDlgPresent = true;		if (this.dlg) {			var $AjaxUmContainer = $('#AjaxUmContainer');			$AjaxUmContainer.append('' + mw.html.escape(this.i18n.umFillInUser) + ' ' + this.umInitImgUserExists.replace('%ID%', 'umUserExists') + ' ');			this.$tagSelect = $(' ', { size : '1', id  : 'umTagToInsert', style: 'width: 99%;' } );			$AjaxUmContainer.append([ '' + mw.html.escape(this.i18n.umSelectTag) + ' ', this.$tagSelect, ' ', ' ' + mw.html.escape(this.i18n.umFillInMedia) + '   ', ' ' + mw.html.escape(this.i18n.umFillInAdditional) + '   ', ' ' + mw.html.escape(this.i18n.umFillInAdditional) + '   ', ' ' + mw.html.escape(this.i18n.umFillInRelUser) + ' ' + this.umInitImgUserExists.replace('%ID%', 'umRelatedUserExists') + '  ', ' <label for="umSummary">' + mw.html.escape(this.i18n.umFillInSummary) + ' <input type="text" id="umSummary" style="width: 95%;" value="Summary"/>  ', '<label for="umAddText">' + mw.html.escape(this.i18n.umAddText) + ' <textarea id="umAddText" style="width: 95%; height: 5em;">' + (mw.html.escape(window.AxUserMsgCustomText || '')) + ' ' ]);			this.talkTag = '';			var	$umMedia      = $('#umMedia'),				$umP2          = $('#umP2'),				$umP3          = $('#umP3'),				$umUser        = $('#umUser'),				$umRelatedUser = $('#umRelatedUser'),				$umSummary     = $('#umSummary'),				$umAddText     = $('#umAddText');			this.uUPC = new ClsUPC($umUser, $('#umUserExists'), 'umUserExistsCB', this, this.umFillSelect);			this.ouUPC = new ClsUPC($umRelatedUser, $('#umRelatedUserExists'), 'umUserExistsCB', this, this.umUserValidChange);			var submitButton = $('.ui-dialog-buttonpane button:first');			this.$tagSelect.keyup( function(event) { if (13 === event.which) submitButton.click; });			// guessing the related file thanks User:Platonides			var guessFile = function {				var f = mw.util.getParamValue('title', document.referrer);				if (f && /File:/.test(f)) return f;				f = mw.util.getParamValue('page', document.referrer);				if (f && /File:/.test(f)) return f;				f = mw.util.getParamValue('target', document.referrer);				if (f && /File:/.test(f)) return f;				var m = document.referrer.match(/File:(.+)/);				try {					if (m) { if (/&.+=/.test(m[1])) return('File:' + decodeURI(m[1]).match(/^(.+)&/)[1]); else return('File:' + m[1]); }				} catch (ex) {}			};			var umFile = guessFile;			if (umFile) $umMedia.val(decodeURIComponent(umFile).replace(/_/g, ' '));			$umUser.keyup( function(event) { $(this).val( $(this).val.replace(/<|>|\^/g, '') ); if (event) if (event.which) if (13 === event.which) submitButton.click; });			$umUser.autocomplete({ minLength: 1, source: function ( request, callback ) { _this.umSeekUsers( request, callback ); }, close: function( event, ui ) { $umUser.triggerHandler('selected'); } });			$umMedia.change( function { _this.umValidateInput(_this); });			$umMedia.on('input', function { $(this).val( $(this).val.replace(/<|>|\^/g, '') ); _this.umValidateInput(_this); });			$umMedia.keyup( function(event) { $(this).val( $(this).val.replace(/<|>|\^/g, '') ); if (13 === event.which) submitButton.click; });			$umMedia.autocomplete({ minLength: 1, source: function ( request, callback ) { _this.umSeekFiles( request, callback ); }, close: function( e, ui ) { $umMedia.triggerHandler('input'); } });			$umRelatedUser.keyup( function(event) { $(this).val( $(this).val.replace(/<|>|\^/g, '') ); if (event) if (event.which) if (13 === event.which) submitButton.click; _this.umValidateInput(_this); });			$umRelatedUser.autocomplete({ minLength: 1, source: function ( request, callback ) { _this.umSeekUsers( request, callback ); }, close: function( e, ui ) { $umRelatedUser.triggerHandler('selected'); } });			$umP2.change( function { _this.umValidateInput(_this); });						$umP2.on('input', function { _this.umValidateInput(_this); });			$umP2.keyup( function(event) { if (13 === event.which) submitButton.click; });			$umP3.change( function { _this.umValidateInput(_this); });						$umP3.on('input', function { _this.umValidateInput(_this); });			$umP3.keyup( function(event) { if (13 === event.which) submitButton.click; });			$umAddText.change( function { _this.umValidateInput(_this); });			$umAddText.on('input', function { _this.umValidateInput(_this); });			$umSummary.keyup( function(event) { if (13 === event.which) submitButton.click; });			submitButton.focus;			$AjaxUmContainer.append(this.umInstPrevContainer.clone.text('Instant-preview container is empty.'));			this.$tagSelect.change( function (/* e*/) { var umType = _this.umTemplate[$(this).val][3]; $umSummary.val(_this.umTemplate[$('#umTagToInsert').val][4] ? _this.umTemplate[$('#umTagToInsert').val][4] : (_this.umTemplate[$('#umTagToInsert').val][2] + '.')); _this.umValidateInput(_this); _this.$tagSelect.combobox({'displaytext': _this.$tagSelect.val ? _this.$tagSelect.children( ":selected" ).text : ""});

if (umType & _this.umFlagP2) { $('#umP2Wrapper').show; if (document.activeElement) if ($umUser.attr('id') !== $(document.activeElement).attr('id')) $('#umP2').select; } else { $('#umP2Wrapper').hide; }				if (umType & _this.umFlagP3) { $('#umP3Wrapper').show; if (document.activeElement) if ($umUser.attr('id') !== $(document.activeElement).attr('id')) $('#umP3').select; } else { $('#umP3Wrapper').hide; }				if (umType & _this.umFlagMQ) { $('#umMediaWrapper').show; if (document.activeElement) if ($umUser.attr('id') !== $(document.activeElement).attr('id')) $('#umMedia').select; } else { $('#umMediaWrapper').hide; }				if (umType & _this.umFlagUQ) { $('#umRelatedUserWrapper').show; if (document.activeElement) if ($umUser.attr('id') !== $(document.activeElement).attr('id')) $('#umMedia').select; } else { $('#umRelatedUserWrapper').hide; }			});			if (window.AxUserMsgPreSelect) this.$tagSelect.val(window.AxUserMsgPreSelect);			$('#umUser').keyup;			$('#umTagToInsert').combobox;		}	},	umSeekUsers: function ( request, pCallback ) {		var query = {			action: 'query',			list: 'allusers',			auprefix: request.term.replace(/^(?:User):/, "")		};		this.doGetApiCall(query, 'umSeekUsersCB', pCallback);	},	umSeekUsersCB: function ( result, pCallback ) {		var searchTerms = [];		$.each(result, function(id, usi) { searchTerms.push( { 'id': usi.userid, 'value': usi.name } ); });		if ('function' === typeof pCallback) pCallback(searchTerms);	},	umSeekFiles: function ( request, pCallback ) {		var query = {			action: 'query',			list: 'allimages',			aiprefix: request.term.replace(/^(?:File|Image):/, "")		};		this.doGetApiCall(query, 'umSeekFilesCB', pCallback);	},	umSeekFilesCB: function ( result, pCallback ) {		var searchTerms = [];		$.each(result, function(id, fii) { searchTerms.push( { 'id': fii.timestamp, 'value': 'File:' + fii.name } ); });		if ('function' === typeof pCallback) pCallback(searchTerms);	},	umUserExistsCB: function (result) {		this.umCurrentUserQuery.evalAPICall(result);	},	umShowInfo: function(info, o) {		$('#umInstantPreviewContainer').empty.html(' <img src="' + o.umImgInfo + '" width="64" height="64"/> ' + info + ' ');	},	umValidateInput: function (o) {		this.umIsValid = true;		var umType = this.umTemplate[$('#umTagToInsert').val][3];		var submitButton = $('.ui-dialog-buttonpane button:first');		var validRelatedUser = function { 			if (umType & o.umFlagUQ) { 				if (o.umCleanFileAndUser($('#umRelatedUser').val).length < 1 ) {					o.umShowInfo('No related user specified.', o);					return false;				}				if ( !o.ouUPC.userNameExists ) {					o.umShowInfo('Related user does not exist.', o);					return false;				}			} 			return true; };		var validMedia = function { 			if (umType & o.umFlagMQ) {				if ( (o.umCleanFileAndUser($('#umMedia').val).length < 5 ) && (umType & o.umFlagReq) ) {					o.umShowInfo('No file specified. This is mandatory in this case.', o);					return false;				}			}			return true; };		var validUser = function {			if ( o.umCleanFileAndUser($('#umUser').val).length < 1 ) { 				o.umShowInfo('No user specified.', o);				return false;			}			if ( !o.uUPC.userNameExists ) { 				o.umShowInfo('User does not exist.', o);				return false;			}			return true; };		this.umIsValid = this.umIsValid && validRelatedUser && validMedia && validUser;		if (this.umIsValid) {			submitButton.removeClass('ui-state-disabled');			if (umType & this.umFlagMQ) {				this.talkTag = '\n{{subst:' + this.umTemplate[$('#umTagToInsert').val][0] + 					(this.umCleanFileAndUser($('#umMedia').val) ? ('|1=' + ((umType & this.umFlagNS) ? ('File:' + this.umCleanFileAndUser($('#umMedia').val)) : $('#umMedia').val)) : '' );			} else if (umType & this.umFlagUQ) {				this.talkTag = '\n{{subst:' + this.umTemplate[$('#umTagToInsert').val][0] + '|1=' + this.umCleanFileAndUser($('#umRelatedUser').val);			}			else {				this.talkTag = '\n{{subst:' + this.umTemplate[$('#umTagToInsert').val][0];			}			var paramCount = ((umType & this.umFlagUQ) ? 1 : 0) + ((umType & this.umFlagMQ) ? 1 : 0);			if (umType & this.umFlagP2) {				paramCount++;				this.talkTag += '|' + paramCount + '=' + $('#umP2').val;			}			if (umType & this.umFlagP3) {				paramCount++;				this.talkTag += '|' + paramCount + '=' + $('#umP3').val;			}			this.talkTag += '}}';			if ('\n' === this.talkTag) this.talkTag = '\n';			this.talkTag += '\n' + $('#umAddText').val.replace(/~{3,5}$/, ) + '~\n';			this.umParseTemplate(false);			// If the user wants the old behaviour back, we fire immediately			if (this.fireImmediately) this.umNotifyUserExecute;		} else {			submitButton.addClass('ui-state-disabled');		}	},	umUserValidChange: function (caller, o) {		o.umValidateInput(o);	},	umCleanFileAndUser: function (input) {		var output = ;		if (input) {			output = input.replace(/\_/g, " ").replace(/File\:/g, "").replace(/Image\:/g, "").replace(/User\:/g, "").replace(/^\s+|\s+$/g, '');			output = output.substring(0, 1).toUpperCase + output.substring(1); }		return output; },	umParseTemplate: function (viaSetTimeout) { if (window.AxUserMsgNoParse) return; var _this = this; if (viaSetTimeout) _this.umPendingParserTimeouts--; if (_this.umPendingParser > 0) { if (!_this.umPendingParserTimeouts) { // call me later var o = _this; _this.umPendingParserTimeouts++; setTimeout( function { 					o.umParseTemplate(true);				}, 300); }			return; }		function maybeParse { _this.umPendingParser++; var action = { action: 'parse', uselang: mw.config.get('wgUserLanguage'), redirects: true, prop: 'text', pst: true, title: _this.umUserTalkPrefix + $('#umUser').val, text: _this.talkTag };			_this.umDelay = Math.min((_this.umDelay + 30), 1500); // Save server resources. _this.doAPICall(action, 'umParsedTemplate'); }		if (_this.umParserTimerID) { clearTimeout(_this.umParserTimerID); }		_this.umParserTimerID = setTimeout( maybeParse, _this.umDelay ); },	umParsedTemplate: function(result) { this.umPendingParser--; if ( 'object' === typeof(result.parse) && ('object' === typeof(result.parse.text)) && this.umDlgPresent && (!this.umExecuting) && this.umIsValid ) { var $containerText = result.parse.text['*'].replace(' API', ' ' + this.umCleanFileAndUser($('#umUser').val)).replace('>API', '>' + this.umCleanFileAndUser($('#umUser').val)); $containerText = $($containerText); $('.editsection', $containerText).remove; $('a', $containerText).attr('target', '_blank'); $('#umInstantPreviewContainer').empty.append($containerText).resizable({ alsoResize: '#AjaxUmContainer' }); }	},	umObtainEditToken: function { if (mw.user && mw.user.tokens) this.editToken = mw.user.tokens.get( 'editToken' ); this.editToken = (this.editToken || (mw.user.isAnon ? '+\\' : '') );		if (this.editToken) return; var query = { action: 'query', prop: 'info', intoken: 'edit', titles: 'FAQ' // Random title };		this.doAPICall(query, 'umObtainEditTokenCB'); },	umObtainEditTokenCB: function (result) { var pages = result.query.pages; for (var id in pages) { // there should be only one, but we don't know its ID			if (pages.hasOwnProperty(id)) { this.editToken = pages[id].edittoken; }		}	},	umNotifyUserExecute: function { if (this.umExecuting) return; this.pageName = this.umUserTalkPrefix + $('#umUser').val; this.talkSummary = $('#umSummary').val; this.appendTemplate; },	appendTemplate: function { var page = []; page.title = this.pageName; page.text = this.talkTag; page.editType = 'appendtext'; page.redirect = true; if (window.AjaxDeleteWatchFile) page.watchlist = 'watch'; this.umExecuting = true; $('#umInstantPreviewContainer').empty.html(' <img src="//upload.wikimedia.org/wikipedia/commons/c/ce/RE_Ajax-Loader.gif"/> '); this.savePage(page, this.talkSummary, 'umNotifyUserExecuteCB'); },	savePage: function (page, summary, callback) { var edit = { action: 'edit', summary: summary, watchlist: (page.watchlist || 'preferences'), title: page.title };		if (page.redirect) edit.redirect = ''; edit[page.editType] = page.text; edit.token = this.editToken; this.doAPICall(edit, callback); },	umNotifyUserExecuteCB: function (/* result*/) { var encTitle = this.umUserTalkPrefix + $('#umUser').val; encTitle = encodeURIComponent(encTitle.replace(/ /g, '_')).replace(/%2F/ig, '/').replace(/%3A/ig, ':'); var newLoc = mw.config.get('wgServer') + mw.config.get('wgArticlePath').replace("$1", encTitle); if (window.location.pathname === mw.config.get('wgArticlePath').replace("$1", encTitle)) { window.location.hash = '#footer'; window.location.reload; } else { window.location.href = newLoc + '#footer'; }		this.umExecuting = false; },	doGetApiCall: function (params, callback, pCallback) { var o = this; // Local Cache if (params.list) { if ("allusers" === params.list) { if (params.auprefix in o.umUserCache) { o[callback](o.umUserCache[params.auprefix], pCallback); return; }			} else if ("allimages" === params.list) { if (params.aiprefix in o.umFileCache) { o[callback](o.umFileCache[params.aiprefix], pCallback); return; }			}		}		params.format = 'json'; $.ajax({			url: this.apiURL,			cache: true,			dataType: 'json',			data: params,			type: 'GET',			async: true,			success: function (result, status, x) {				if (!result) { if ('function' === typeof pCallback) pCallback; return; }				try {					if (params.list) if ("allusers" === params.list) {						// cache the result						o.umUserCache[ params.auprefix ] = result.query.allusers;						o[callback](result.query.allusers, pCallback);						return;					}					if (params.list) if ("allimages" === params.list) {						// cache the result						o.umFileCache[ params.aiprefix ] = result.query.allimages;						o[callback](result.query.allimages, pCallback);						return;					}					// This is a "must", the doc sais					if ('function' === typeof pCallback) pCallback;					o[callback](result);				} catch (e) {					return o.fail(e);				}			},			error: function {				// This is a "must", the doc sais				if ('function' === typeof pCallback) pCallback; }		});	},	doAPICall: function (params, callback) {		var o = this;		if (params.action) if ("parse" === params.action) {			if (params.text in o.umParserCache) {				o[callback](o.umParserCache[params.text]);				return;			}		}		params.format = 'json';		$.ajax({ url: this.apiURL, cache: false, dataType: 'json', data: params, type: 'POST', success: function (result, status, x) { if (!result) return o.fail("Receive empty API response:\n" + x.responseText); // In case we get the mysterious 231 unknown error, just try again if (result.error && result.error.info.indexOf('231') !== -1) return setTimeout(function {					o.doAPICall(params, callback);				}, 500); if (result.error) return o.fail("API request failed (" + result.error.code + "): " + result.error.info); if (result.edit && result.edit.spamblacklist) { return o.fail("ERROR: The edit failed because " + result.edit.spamblacklist + " is on the Spam Blacklist"); }				if (params.action) if ("parse" === params.action) { o.umParserCache[params.text] = result; }				try { o[callback](result); } catch (e) { return o.fail(e); }			},			error: function (x, status, error) { return o.fail("API request returned code " + x.status + " " + status + "Error code is " + error); }		});	},	fail: function (err) {		if ('object' === typeof err) {			var stErr = mw.html.escape(err.message) + ' ' + err.name;			if (err.lineNumber) stErr += ' @line' + err.lineNumber;			if (err.line) stErr += ' @line' + err.line;			err = stErr;		} else {			err = mw.html.escape(err.toString);		}		if (this.umDlgPresent) {			$('#umInstantPreviewContainer').empty.html(' <img src="' + this.umImgErr + '" width="64" height="64"/> ' + "During the execution of AxUserMsg, the following error occured: " + mw.html.escape(err));		} else {			jsMsgAppend("During the execution of AxUserMsg, the following error occured: " + err);		}	},	i18n: {		umFillInUser: "Please fill in the username (the username without the User: prefix) to notify:",		umSelectTag: "Select the template to be added to the user's page. Insert text into the box to filter:",		umFillInMedia: "Please specify the page this message is about (namespace will be auto-detected):",		umFillInAdditional: "The template has an additional parameter. You can fill it in here.",		umFillInRelUser: "Who is the user related to this message?",		umFillInSummary: "Edit summary",		umAddText: "Fill in additional text to place on the user's discussion page, please:",		submitButtonLabel: "✔ Add template",		cancelButtonLabel: "❌  Cancel"	},	umInstPrevContainer: $(' ', { id: 'umInstantPreviewContainer', style: 'background-color:#EFD;height:380px;overflow:scroll;vertical-align:middle;' }), umInitImgUserExists: '<img id="%ID%" src="//upload.wikimedia.org/wikipedia/commons/thumb/4/42/P_no.svg/20px-P_no.svg.png" alt="?"/>', umImgUserUndefined: '//upload.wikimedia.org/wikipedia/commons/thumb/4/42/P_no.svg/20px-P_no.svg.png', umImgUserNotExists: '//upload.wikimedia.org/wikipedia/commons/thumb/4/42/P_no_red.svg/20px-P_no_red.svg.png', umImgUserExists: '//upload.wikimedia.org/wikipedia/commons/thumb/b/be/P_yes.svg/20px-P_yes.svg.png', umImgUserIsIP: '//upload.wikimedia.org/wikipedia/commons/thumb/6/6e/IP.svg/20px-IP.svg.png', umImgErr: '//upload.wikimedia.org/wikipedia/commons/c/ca/Crystal_error.png', umImgWarn: '//upload.wikimedia.org/wikipedia/commons/a/af/Crystal_Clear_app_error-info.png', umImgInfo: '//upload.wikimedia.org/wikipedia/commons/0/09/Crystal_Clear_action_info.png', umFlagMQ: 1,  // Media Query umFlagUQ: 2,  // Username Query umFlagReq: 4, // Required - must filled in	umFlagNS: 8,   // Add Namespace umFlagP2: 16, // add a universal parameter umFlagP3: 32, // add a universal parameter umFlagIP: 64, // Message for IP only umFlagUM: 128, // User message only umFlagReqMqNs: 13, // Combination of (umFlagReq | umFlagMQ | umFlagNS) umUserTalkPrefix: mw.config.get('wgFormattedNamespaces')[3] + ":", apiURL: mw.util.wikiScript( 'api' ) }; umsg.umTemplate = [ /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * Append new messages at the bottom. Otherwise pre-selection for users will break. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ // ['Template name',             "Name in Sidebar", "Detailed text",                                                                          Type/Prompt statement,           'Talk summary']; ['uw-vandalism',             "Vandalism",     "Warning for vandalism",                                                                    umsg.umFlagUM, "Warning: Vandalism"], ['uw-delete',              "Removing content",     "Do not remove content from pages",                                    umsg.umFlagUM + umsg.umFlagReqMqNs, 'Notice: Do not remove content from pages.'], ['uw-test',           "Test edits",  "Making test edits in pages",                         umsg.umFlagUM + umsg.umFlagReqMqNs, 'Notice: Making test edits.'], ['uw-wrong',              "False information",     "Don't add false information",                                      umsg.umFlagUM + umsg.umFlagReqMqNs, 'Please do not add false information please'], ['User:Psl85/Delete-notice',       "Deletion notice",     "Note the user if their page the user created has been marked for deletion",                                       umsg.umFlagUM + umsg.umFlagReqMqNs, 'Notification: Your page has been tagged for deletion.'], ['User:Psl85/editwar-warning',        "Edit war warning",      "Warn the user that they has edit warred",                                                  umsg.umFlagUM, "Warning: Edit warring"], ['User:Psl85/redlinks',   "Do not remove red links", "Give user a noticce to not remove red links",                                             umsg.umFlagUM + umsg.umFlagReqMqNs, 'Notice: Do not remove useful red links'], ['User:Psl85/grammar',            "Grammar",   "Inform user that do not use goog grammar",                 umsg.umFlagMQ, "Please do not use bad grammar"], ['User:Psl85/read-mos',              "Read the Manual of Style",  "Inform user to read the Manual of Style",                                                          0, "Please read the style guide."], ['Welcome',                  "Welcome",         "Welcome a new user or a user who has not yet received a welcome message",                0, "Hello, Welcome to Minecraft Wiki! - A wiki about the Minecraft video game."], ['Welcome anon',          "Welcome (anon)",     "Welcome, Please create an account or sign in",                     umsg.umFlagUM, "Welcome!."], ['Welcome-unconstructive',                      "Welcome (unconstructive)",    "Give user a welcome message but have made bad edits",                     umsg.umFlagUM, "Welcome."], ['Blcoked',                "Banned",       "You have been banned from editing.",                                                        0, "Your account or IP address has been blocked from editing."], ['',                         "Select a message! Empty option.", "A new message for you!",                                                 0] ];

/** * A custom widget built by composition of Autocomplete and Button. * You can either type something into the field to get filtered suggestions based on your input, * or use the button to get the full list of selections. * * The input is read from an existing select-element for progressive enhancement, * passed to Autocomplete with a customized source-option. * * Autor: someone from the jQuery UI-Team? * slightly altered var initCombobox = function( $ ) { $.widget( 'ui.combobox', {	// These options will be used as defaults	options: { 		displaytext: '',		emptyMessage: 42,		passEnter: true,		shutOff: window.AxUserMsgUseSelect	},

// Use the _setOption method to respond to changes to options _setOption: function(key, value) { if (this.options.shutOff) return; switch( key ) { case 'displaytext': this.input.val(value); break; case 'passEnter': this.options.passEnter = value; break; }

// In jQuery UI 1.8, you have to manually invoke the _setOption method from the base widget $.Widget.prototype._setOption.apply( this, arguments ); },	_create: function { if (this.options.shutOff) return; var self = this, select = this.element.hide, selectWidth = select.width, selectId = select.attr('id'), selectLabels, selected = select.children( ":selected" ), value = selected.val ? selected.text : "", ownId = 'j' + Math.floor(Math.random * 10000000000), isOpen = false, valid = true; if (selectId) { selectLabels = $('label[for="' + selectId + '"]'); }		var portMessure = this.portMessure = $(' ', { id: ownId + 'vp' }).css({ position: 'fixed', top: '0', height: '0' }); $('body').append(portMessure); var input = this.input = $( " ", { id: ownId } ) .insertAfter( select ) .val( value ) .autocomplete({				delay: 0,				minLength: 0,				source: function( request, response ) {					var i = 0,						matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" );

response( select.children( "option" ).map(function { if ( (i > (window.AxUserMsgMaxSelect || 20)) && request.term ) return; var text = $( this ).text; if ( this.value && ( !request.term || matcher.test(text) ) ) { i++; return { label: text.replace(									new RegExp( "(?![^&;]+;)(?!<[^<>]*)(" +										$.ui.autocomplete.escapeRegex(request.term) +										")(?![^<>]*>)(?![^&;]+;)", "gi" ), "$1" ),								value: text, option: this };						}					}) );				},				select: function( event, ui ) { ui.item.option.selected = true; self._trigger( "selected", event, {						item: ui.item.option					}); select.triggerHandler('change'); },				change: function( event, ui ) { if ( !ui.item ) { var matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex( $(this).val ) + "$", "i" ); valid = false; select.children( "option" ).each(function {							if ( $( this ).text.match( matcher ) ) {								this.selected = valid = true;								return false;							}						}); if ( !valid ) { // remove invalid value, as it didn't match anything $( this ).val( "" ); input.data( "autocomplete" ).term = ""; select.val(self.options.emptyMessage); select.triggerHandler('change'); return false; } else { select.triggerHandler('change'); }					}				},				create: function (e, ui) { var _t = $(this), t_top = _t.offset.top - portMessure.offset.top; $('.ui-autocomplete.ui-menu').css({						'position': 'fixed',						'overflow': 'auto',						'max-height': Math.round($(window).height - t_top - _t.height - 20 ) + 'px'					}); },				close: function (e, ui) { setTimeout( function { isOpen = false; }, 1 ); }, open: function (e, ui) { isOpen = true; var _t = $(this), t_top = _t.offset.top - portMessure.offset.top; $('.ui-autocomplete.ui-menu') .css({							'position': 'fixed',							'max-height': Math.round($(window).height - t_top - _t.height - 20 ) + 'px'						}); }			})			.addClass( "ui-widget ui-widget-content ui-corner-left" ).css('width', (selectWidth - 70) + 'px')			.click(function { $(this).select; })			.keydown(function(e) { if (self.options.passEnter && (13 === e.which) && !isOpen && valid) { var kup = $.Event("keyup"); kup.ctrlKey = false; kup.keyCode = kup.which = 13; select.triggerHandler(kup); }			});		if (selectLabels) {			selectLabels.attr('for', ownId);		}

input.data( "autocomplete" )._renderItem = function( ul, item ) { return $( "<li>" ) .data( "item.autocomplete", item ) .append( "" + item.label + "</a>" ) .appendTo( ul ); };

this.button = $( " ", {			"tabIndex": -1,			"type": "button",			"text": " ",			"title": "Show All Items",			"style": "height:1.5em;padding:0!important;width:20px;margin:0!important;position:relative;top:5px;"		} ) .insertAfter( input ) .button({				icons: {					primary: "ui-icon-triangle-1-s"				},				text: false			}) .removeClass( "ui-corner-all" ) .addClass( "ui-corner-right ui-button-icon" ) .click(function {				// close if already visible				if ( input.autocomplete( "widget" ).is( ":visible" ) ) {					input.autocomplete( "close" );					return;				}

// work around a bug (likely same cause as #5265) $( this ).blur;

// pass empty string as value to search for, displaying all results input.autocomplete( "search", "" ); input.focus; });	},

destroy: function { if (this.options.shutOff) return; this.input.remove; this.portMessure.remove; this.button.remove; this.element.show; $.Widget.prototype.destroy.call( this ); } }); };

if ($.inArray(mw.config.get('wgNamespaceNumber'), [-1, 2, 3]) !== -1) { // alternative for jquery.ui.autocomplete: jquery.suggestions // http://jqueryui.com/demos/autocomplete/ http://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/resources/jquery/jquery.suggestions.js?view=markup $.when(mw.loader.using([ 'jquery.ui.dialog', 'jquery.ui.autocomplete', 'jquery.ui.resizable', 'mediawiki.util', 'mediawiki.user', 'ext.gadget.libUtil', 'ext.gadget.libJQuery' ]), $.ready) .then(function {			initCombobox($);			umsg.umInstall;			if (window.installOldLinks) umsg.umInstallOldLinks;			$(document).triggerHandler('scriptLoaded', ['AxUserMsg', umsg]);	}); } }); //