Jump to content

User:PleaseStand/userinfo-dev.js

From Wikipedia, the free encyclopedia
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
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.
// based on http://en.wikipedia.org/wiki/User:Fran_Rogers/dimorphism.js 
// and on http://en.wikipedia.org/wiki/User:Splarka/sysopdectector.js

( function ( mw, $ ) {

	var h = mw.html,
		api,
		ns = mw.config.get( 'wgNamespaceNumber' ),
		title = mw.config.get( 'wgTitle' );

	// Bail out unless on a user or user talk page, and not a subpage.
	if ( ns !== 2 && ns !== 3 || title.indexOf( '/' ) >= 0 ) {
		return;
	}

	// TODO: add additional languages
	mw.messages.set( {
		'ps-userinfo-gendersymbol-male': '♂',
		'ps-userinfo-gendersymbol-female': '♀',
		'ps-userinfo-gendersymbol-unknown': '',
		'ps-userinfo-itemseparator': '$1\u00a0| $2',
		'ps-userinfo-groupseparator': '$1, $2',

		'ps-userinfo-seconds': '$1 {{PLURAL:$1|second|seconds}}',
		'ps-userinfo-minutes': '$1 {{PLURAL:$1|minute|minutes}}',
		'ps-userinfo-hours': '$1 {{PLURAL:$1|hour|hours}}',
		'ps-userinfo-days': '$1 {{PLURAL:$1|day|days}}',
		'ps-userinfo-weeks': '$1 {{PLURAL:$1|week|weeks}}',
		'ps-userinfo-months': '$1 {{PLURAL:$1|month|months}}',
		'ps-userinfo-years': '$1 {{PLURAL:$1|year|years}}',
		'ps-userinfo-years-months': '$1 {{PLURAL:$1|year|years}} $2 {{PLURAL:$2|month|months}}',

		'ps-userinfo-blocked': 'BLOCKED',
		'ps-userinfo-editcount': '$1 {{PLURAL:$1|edit|edits}}',
		'ps-userinfo-invalid': 'invalid username',
		'ps-userinfo-ipv4': 'IPv4 address',
		'ps-userinfo-ipv6': 'IPv6 address',
		'ps-userinfo-lastedited': 'last edited [$2 $1 ago]',
		'ps-userinfo-missing': 'username not registered',
		'ps-userinfo-registration': '$1 old',
		'ps-userinfo-user': '{{GENDER:$1|registered user}}'
	} );

	/**
	 * Get the user's information by performing an AJAX request and processing the response.
	 * @param {string} userName The user to retrieve information for
	 * @return {jQuery.Deferred}
	 */
	function getInfo( userName ) {
		return api.get( {
			action: 'query',
			list: 'users|usercontribs',
			maxage: 300,
			uclimit: 1,
			ucprop: 'timestamp',
			ucuser: userName,
			usprop: 'blockinfo|editcount|gender|registration|groups',
			ususers: userName
		} ).then( function ( data ) {
			var query = data.query, user = query.users[0], contribs = query.usercontribs;

			return {
				name: userName,
				isInvalid: 'invalid' in user,
				isIPv4: mw.util.isIPv4Address( userName ),
				isIPv6: mw.util.isIPv6Address( userName ),
				isMissing: 'missing' in user,
				groups: user.groups || [],
				editCount: 'editcount' in user ? user.editcount : null,
				registration: user.registration ? new Date( user.registration ) : null,
				isBlocked: 'blockexpiry' in user,
				gender: user.gender || 'unknown',
				lastEdited: ( contribs && contribs[0] ) ? new Date( contribs[0].timestamp ) : null
			};
		} );
	}

	/**
	 * Display the user's information on screen.
	 * @param info Information about the user
	 */
	function displayInfo( info ) {
		var userPrefix = mw.config.get( 'wgFormattedNamespaces' )[2] + ':',
			items = [],
			groups = [],
			text = '';

		if ( info.isBlocked ) {
			items.push( h.element( 'a', { href:
				mw.util.wikiScript( 'index' ) + '?' + $.param( {
					title: 'Special:Log',
					page: userPrefix + info.name
				} )
			}, new h.Raw( h.element( 'strong', {}, mw.msg( 'ps-userinfo-blocked' ) ) ) ) );
		}

		if ( info.isMissing ) {
			items.push( mw.message( 'ps-userinfo-missing' ).escaped() );
		} else if ( info.isIPv4 ) {
			items.push( mw.message( 'ps-userinfo-ipv4' ).escaped() );
		} else if ( info.isIPv6 ) {
			items.push( mw.message( 'ps-userinfo-ipv6' ).escaped() );
		} else if ( info.isInvalid ) {
			items.push( mw.message( 'ps-userinfo-invalid' ).escaped() );
		} else {
			$.each( info.groups, function ( i, v ) {
				if ( $.inArray( v, ['*', 'user', 'autoconfirmed'] ) < 0 ) {
					groups.push( mw.message( 'group-' + v + '-member', info.gender ).escaped() );
				}
			} );
			if ( groups.length ) {
				items.push( groups.join( mw.message( 'ps-userinfo-groupseparator', '', '' ).escaped() ) );
			} else {
				items.push( mw.message( 'ps-userinfo-user', info.gender ).escaped() );
			}

			if ( info.registration ) {
				items.push( mw.message(
					'ps-userinfo-registration',
					buildDurationMessage( info.registration, new Date() ).text(),
					info.gender
				).escaped() );
			}

			if ( info.editCount !== null ) {
				items.push( h.element( 'a', { href:
					'https://xtools.wmcloud.org/ec/' +
					encodeURIComponent( location.hostname ) + '/' +
					encodeURIComponent( info.name )
				}, mw.message( 'ps-userinfo-editcount', info.editCount ).text() ) );
			}
		}

		if ( info.lastEdited ) {
			items.push( mw.message(
				'ps-userinfo-lastedited',
				buildDurationMessage( info.lastEdited, new Date() ).escaped(),
				$( '<a>' ).prop( 'href', mw.util.getUrl( 'Special:Contributions/' + info.name ) ),
				mw.html.escape( info.name )
			).parse() );
		}

		// Add the gender symbol after the user's name
		$( '<span>' )
			.prop( 'id', 'ps-gender-' + info.gender )
			.css( {
				paddingLeft: '0.25em',
				fontFamily: '"Lucida Grande", "Lucida Sans Unicode", sans-serif',
				fontSize: '75%'
			} )
			.text( mw.msg( 'ps-userinfo-gendersymbol-' + info.gender ) )
			.appendTo( '#firstHeading' );

		// Replace the subtitle with the rest of the info
		$( '#siteSub' ).html( items.join( mw.message( 'ps-userinfo-itemseparator', '', '' ).escaped() ) );
	}

	/**
	 * Load messages corresponding to MediaWiki user groups into mw.messages.
	 * @return {jQuery.Deferred}
	 */
	function loadGroupMemberMessages() {
		return api.get( {
			action: 'query',
			amfilter: '-member',
			amlang: mw.config.get( 'wgUserLanguage' ),
			amprefix: 'group-',
			maxage: 86400,
			meta: 'allmessages'
		} ).then( function ( data ) {
			$.each( data.query.allmessages, function ( i, message ) {
				mw.messages.set( message.name, message['*'] );
			} );
		} );
	}

	/**
	 * Convert a duration to a message object.
	 * @param {Date} start The duration's start
	 * @param {Date} end The duration's end
	 * @return {mediaWiki.Message}
	 */
	function buildDurationMessage( start, end ) {
		var age = ( end - start ) / 1000; // start with seconds
		if ( age < 60 ) {
			return mw.message( 'ps-userinfo-seconds', Math.floor( age ) );
		}

		age /= 60; // convert to minutes
		if ( age < 60 ) {
			return mw.message( 'ps-userinfo-minutes', Math.floor( age ) );
		}

		age /= 60; // convert to hours
		if ( age < 24 ) {
			return mw.message( 'ps-userinfo-hours', Math.floor( age ) );
		}

		age /= 24; // convert to days
		if ( age < 7 ) {
			return mw.message( 'ps-userinfo-days', Math.floor( age ) );
		}

		age /= 7; // convert to weeks
		if ( age < 4.3481 ) {
			return mw.message( 'ps-userinfo-weeks', Math.floor( age ) );
		}

		age /= 4.3481; // convert to months
		if ( age < 12 ) {
			return mw.message( 'ps-userinfo-months', Math.floor( age ) );
		}

		// convert to years and months
		var years = Math.floor( age / 12 ), months = Math.floor( age % 12 );
		if ( months ) {
			return mw.message( 'ps-userinfo-years-months', years, months );
		}
		return mw.message( 'ps-userinfo-years', years );
	}

	mw.loader.using( [
		'mediawiki.api',
		'mediawiki.jqueryMsg',
		'mediawiki.language',
		'mediawiki.util'
	], function () {
		api = new mw.Api();
		loadGroupMemberMessages().done( function () {
			getInfo( title ).done( displayInfo );
		} );
	} );
	
} )( mediaWiki, jQuery );