MediaWiki:Gadget-AbstractWikipediaDraggableVoting.js

From Meta, a Wikimedia project coordination wiki

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
/**
 * Forked from https://www.mediawiki.org/wiki/MediaWiki:Gadget-logo-voting.js
 */

/* eslint-disable one-var, vars-on-top, no-jquery/no-sizzle, es/no-object-values */

( function () {
	// eslint-disable-next-line no-restricted-properties
	if ( !mw.config.get( 'wgPageName' ).startsWith( 'Abstract_Wikipedia/Wiki_of_functions_naming_contest/Names' ) ) {
		return;
	}

	/**
	 * Shuffles array in place.
	 *
	 * @param {Array} a items An array containing the items.
	 * From https://stackoverflow.com/a/6274381/2596051
	 * @return {Array} The array, sorted.
	 */
	function shuffle( a ) {
		var j, x, i;
		for ( i = a.length - 1; i > 0; i-- ) {
			j = Math.floor( Math.random() * ( i + 1 ) );
			x = a[ i ];
			a[ i ] = a[ j ];
			a[ j ] = x;
		}
		return a;
	}

	function main() {

		var DraggableGroupWidget = function DraggableGroupWidget( config ) {
			config = config || {};
			DraggableGroupWidget.super.call( this, config );
			OO.ui.mixin.DraggableGroupElement.call( this, $.extend( {
				$group: this.$element
			}, config ) );
		};
		OO.inheritClass( DraggableGroupWidget, OO.ui.Widget );
		OO.mixinClass( DraggableGroupWidget, OO.ui.mixin.DraggableGroupElement );

		var DraggableItemWidget = function DraggableItemWidget( config ) {
			config = config || {};
			DraggableItemWidget.super.call( this, config );
			OO.ui.mixin.DraggableElement.call( this, config );
		};
		OO.inheritClass( DraggableItemWidget, OO.ui.Widget );
		OO.mixinClass( DraggableItemWidget, OO.ui.mixin.DraggableElement );

		var items = [];
		// eslint-disable-next-line no-jquery/no-global-selector
		$( '.wikitable tr' ).each( function ( i ) {
			// Skip the first two rows.
			if ( i < 2 ) {
				return;
			}
			var element = new DraggableItemWidget( {
				content: [ new OO.ui.HtmlSnippet( '<br>' ), new OO.ui.HtmlSnippet( $( this ).find( 'td:eq(2) img' ).clone() ) ],
				data: $( this ).find( 'td:first' ).text(),
				text: $( this ).find( 'td:first' ).text() + ' - ' + $( this ).find( 'td:eq(1)' ).text()
			} );
			element.$element
				.css( 'border', '1px solid #a2a9b1' )
				.css( 'background-color', '#f8f9fa' )
				.css( 'padding', '5px' )
				.css( 'border-radius', '2px' )
				.css( 'margin', '5px' );
			items.push( element );
		} );
		shuffle( items );

		var noticeText = '<strong>' +
				mw.msg( 'gadget-logo-voting-noticetext' ) +
				'<br>' + mw.msg( 'gadget-logo-voting-voteprompt' ) +
			'</strong><br>',
			draggableGroupWidget = new DraggableGroupWidget( {
				orientation: 'horizontal',
				items: items
			} );
		draggableGroupWidget.$element
			.css( 'border', '1px solid #a2a9b1' )
			.css( 'padding', '5px' )
			.css( 'border-radius', '2px' )
			.css( 'margin', '5px' );

		var massage = new OO.ui.MessageWidget( {
			type: 'notice',
			label: new OO.ui.HtmlSnippet(
				noticeText +
				draggableGroupWidget.getItems().map( function ( i ) {
					return i.getData();
				} ).join( ' - ' ) )
		} );
		draggableGroupWidget.on( 'reorder', function () {
			massage.setLabel( new OO.ui.HtmlSnippet(
				noticeText +
				draggableGroupWidget.getItems().map(
					function ( i ) {
						return i.getData();
					} ).join( ' - ' )
			) );
		} );
		var saveButton = new OO.ui.ButtonInputWidget( {
			type: 'submit',
			label: mw.msg( 'gadget-logo-voting-label' ),
			flags: [
				'primary',
				'progressive'
			]
		} );
		saveButton.on( 'click', function () {
			var api = new mw.Api();
			api.edit( 'Abstract_Wikipedia/Wiki_of_functions_naming_contest/Votes', function ( revision ) {
				return {
					text: revision.content + '\n*[[User:' + mw.config.get( 'wgUserName' ) + ']]: ' + draggableGroupWidget.getItems().map( function ( i ) {
						return i.getData().replace( '\n', '' );
					} ).join( ' - ' ),
					summary: mw.msg( 'gadget-logo-voting-editsummary' )
				};
			} ).done( function () {
				OO.ui.alert( mw.msg( 'gadget-logo-voting-messagetext' ) );
				setTimeout( function () {
					window.location.href = 'https://meta.wikimedia.org/wiki/Abstract_Wikipedia/Wiki_of_functions_naming_contest/Votes';
				}, 5000 );
			} ).fail( function () {
				OO.ui.alert( mw.msg( 'gadget-logo-voting-error' ) );
			} );
		} );

		// eslint-disable-next-line no-jquery/no-global-selector
		var $body = $( '#bodyContent' );
		$body.prepend( draggableGroupWidget.$element );
		massage.$element.append( saveButton.$element );
		$body.prepend( massage.$element );
	}

	function populateMessages() {
		var deferred = new $.Deferred(),
			userLanguage = mw.config.get( 'wgUserLanguage' );

		var api = new mw.Api();
		api.get( {
			action: 'query',
			prop: 'revisions',
			rvslots: '*',
			rvprop: 'content',
			titles: 'MediaWiki:Gadget-AbstractWikipediaDraggableVoting.i18n.' + userLanguage + '.json'
		} ).done( function ( data ) {
			var response = Object.values( data.query.pages )[ 0 ];

			if ( userLanguage !== 'en' && ( !response || ( 'missing' in response ) ) ) {
				// Nothing specified for this language; fallback to English for this run.

				var fallbackApi = new mw.Api();
				fallbackApi.get( {
					action: 'query',
					prop: 'revisions',
					rvslots: '*',
					rvprop: 'content',
					titles: 'MediaWiki:Gadget-AbstractWikipediaDraggableVoting.i18n.en.json'
				} ).done( function ( fallbackData ) {
					var fallbackResponse = Object.values( fallbackData.query.pages )[ 0 ];
					mw.messages.set( JSON.parse( fallbackResponse.revisions[ 0 ].slots.main[ '*' ] ) );
					return deferred.resolve();
				} );
			} else {
				mw.messages.set( JSON.parse( response.revisions[ 0 ].slots.main[ '*' ] ) );
				return deferred.resolve();
			}
		} );

		return deferred;
	}

	// eslint-disable-next-line no-jquery/no-global-selector
	$( '.mw-ui-button.mw-ui-progressive' ).on( 'click', function () {
		mw.loader.using( [ 'oojs-ui-widgets', 'mediawiki.jqueryMsg' ] ).then( function () {
			populateMessages().done(
				function () {
					if ( !mw.config.get( 'wgUserName' ) ) {
						OO.ui.alert( mw.msg( 'gadget-logo-voting-login' ) );
						return;
					}

					main();
				}
			);
		} );
	} );

}() );