User:Adamw/jade-test.js

// 1. Find your common.js //       https://en.wikipedia.org/wiki/Special:MyPage/common.js // 2. Add the following code to it: //       mw.loader.load('/w/index.php?title=User:Prtksxna/jade-test.js&action=raw&ctype=text/javascript'); // 3. Go to History page, for example: //       https://en.wikipedia.org/w/index.php?title=Delhi_Airport_Metro_Express&action=history // 4. Click on a revision that has (fake) judgements, for example: //       https://en.wikipedia.org/w/index.php?title=Delhi_Airport_Metro_Express&diff=839712756&oldid=838620306&diffmode=source // 5. ??? // 6. PROFIT!

mw.loader.using( ['oojs', 'oojs-ui-core', 'oojs-ui-widgets', 'moment', 'mediawiki.api.messages'], function {	// Config	// Also see the following methods below	// - getRandomJudgement	// - hasJudgment	// - getNoOfJudgements	var config = {		'showORES': false,		'singleJudgement': false,		'notesPlaceholder': 'Notes about the judgment',        'labelingHelpUrl': 'https://mediawiki.org/wiki/JADE/Labels'		// TODO: Include a link to the Jade_talk page.	};	// Bootstrap	new mw.Api.getMessages( [ 'damaging', 'february', 'march' ], { amlang: 'en' } ).then( function ( d ) { console.log( d ); }	);	$( function { var currentPage = whichPage; if ( !currentPage ) { return; } else if ( currentPage === 'history' ) { addJudgementsToHistory; } else	if ( currentPage === 'change' ) { addJudgementsToChanges; } else if ( currentPage === 'diff' ) { addJudgementsToDiff; }	} );	// Methods	/*	 * Add judgements to the diff page	**/	function addJudgementsToDiff {		var uriArray = $('#mw-diff-ntitle1').find('a').attr('href').split("=");		var id = uriArray[ uriArray.length - 1 ];		var nOfJ = getNoOfJudgements( id );		var $ores, $newForm, $judgements = $( ' ' ).addClass( 'jade-judgements');		// Actual ORES score		if ( config.showORES ) {			$ores = $( ' ' );			populateORES( id, $ores );		}		// Show a new judgement form if applicable		if ( config.singleJudgement === false || nOfJ === 0 ) {			$newForm = getNewJudgementForm;		}		// Show 'existing' dummy judgements		for( var i = 0; i < nOfJ; i++ ) {			$judgements.append( getJudgementElement( getRandomJudgement( i ) ) );		}		$( 'td.diff-ntitle').append( $( ' ' ).css( 'text-align', 'left').append(				$ores, 				$newForm, 				' Judgements ',				$judgements 			) );	}	function getJudgementElement ( j ) {		var $user = $( '' )			.text( j.user )			.css( 'font-weight', '800' )			.attr( 'href', 'https://en.wikipedia.org/w/index.php?title=User:' + j.user );		var ago = j.ago || moment( new Date(+(new Date) - Math.floor(Math.random*10000000000)) ).fromNow;		var $reason = $( ' ' )			.text( j.reason )			.css( { 'border-top': '1px solid #c8ccd1', 'margin-top': '5px', 'padding': '10px', 'overflow': 'hidden' } )			.hide;		var $deleteButton = new OO.ui.ButtonWidget( { label: 'Delete', icon: 'trash', framed: false, flags: [ 'destructive' ] } ).$element.appendTo( $reason ).css( 'float', 'right' ).on( 'click', function { OO.ui.confirm( 'Are you sure?' ).done( function ( confirmed ) {   			if ( confirmed ) {        			$.fadeOut;    			}			} ); });		var $expandButton = new OO.ui.ButtonWidget( { framed: false, icon: 'expand', title: 'Expand' } ).$element.on('click', function { $reason.slideToggle; }).css( 'float', 'right');

var $j = $( ' ' ).css({			'background': '#eaecf0',			'border-radius': '2px',			'padding': '3px 0',			'margin-bottom': '20px',		}); $.append( $expandButton ); var $vars = $( ' ' ).css( 'margin', '10px'); $.append( $vars ); if ( j.damaging === true ) { $vars.append(				$( ' ' )					.css( { 'color': '#fff', 'background': '#d33', 'border-radius': '2px', 'padding': '3px 15px 6px', 'margin-right': '5px', 'text-transform': 'lowercase', 'font-variant': 'small-caps', 'letter-spacing': '0.3px' })					.text( 'Damaging ')			) } else if ( j.damaging === false ) { $vars.append(				$( ' ' )					.css( { 'color': '#fff', 'background': '#36c', 'border-radius': '2px', 'padding': '3px 15px 6px', 'margin-right': '5px', 'text-transform': 'lowercase', 'font-variant': 'small-caps', 'letter-spacing': '0.3px'

})					.text( 'Not damaging')			) }		if ( j.goodfaith === true ) { $vars.append(				$( ' ' )					.css( { 'color': '#fff', 'background': '#14866d', 'border-radius': '2px', 'padding': '3px 15px 6px', 'margin-right': '5px', 'text-transform': 'lowercase', 'font-variant': 'small-caps', 'letter-spacing': '0.3px'

})					.text( 'Good faith')			) } else if ( j.goodfaith === false ) { $vars.append(				$( ' ' )					.css( { 'color': '#fff', 'background': '#d33', 'border-radius': '2px', 'padding': '3px 15px 6px', 'margin-right': '5px', 'text-transform': 'lowercase', 'font-variant': 'small-caps', 'letter-spacing': '0.3px'

})					.text( 'Bad faith')			) }

$.append( $( ' ' )			.css( 'color', '#54595d' )			.css( 'padding', '0 10px' )			.append( $user )			.append ( ' • ' )			.append( ago )		).append( $reason); return $j; }   // Subclass of exclusive radio group where the active checkbox can be deselected. ButtonDeselectableSelectWidget = function OoUiButtonDeselectableSelectWidget( config ) { ButtonDeselectableSelectWidget.parent.call( this, config );

this.lastSelectedItem = null;

this.connect( this, { choose: 'onChoose' } ); };   OO.inheritClass( ButtonDeselectableSelectWidget, OO.ui.ButtonSelectWidget ); ButtonDeselectableSelectWidget.prototype.onChoose = function ( item ) { if ( item === this.lastSelectedItem ) { // Deselect if the user is clicking on an already selected checkbox. this.selectItem( null ); this.lastSelectedItem = null; } else { this.lastSelectedItem = item; }   };

// Returns a new judement form function getNewJudgementForm { var d = new ButtonDeselectableSelectWidget( {			items: [				new OO.ui.ButtonOptionWidget( { data: 'not damaging', label: 'Not damaging' } ),				new OO.ui.ButtonOptionWidget( { data: 'damaging', label: 'Damaging' } ),			]		} );		var f = new ButtonDeselectableSelectWidget( {			items: [				new OO.ui.ButtonOptionWidget( { data: 'good faith', label: 'Good faith' } ),				new OO.ui.ButtonOptionWidget( { data: 'bad faith', label: 'Bad faith' } ),			]		} );		var r = new OO.ui.MultilineTextInputWidget( {			autosize: true,			rows: 4,			placeholder: config.notesPlaceholder		} ); var s = new OO.ui.ButtonWidget( {			label: 'Add judgement',			flags: ['progressive', 'primary' ]		} ); s.on('click', function {			var j = isValidJudgement( r, d, f );			if ( !j ) {				OO.ui.alert( 'Please enter a judgement' );			} else {				$thanks = $( ' ' )					.text( 'Thank you! Your judgement has been added.' )					.css({ 'padding': '20px', 'background': '#d5fdf4', 'border': '1px solid #14866d', 'color': '#14866d' });				$( ".jade-judgements" ).prepend( getJudgementElement( j ).hide.fadeIn( 2000 ) );				$( ".jade-new" )					.empty					.append( $thanks );			}		} );

var helpLink = $( '' ) .css( {               'margin-left': 'auto',                'margin-right': '1em'            } ).attr( 'href', config.labelingHelpUrl ) .text( 'Help' ); r.$element.find( 'textarea' ).css( 'border-radius', '2px 2px 0 0'); var $buttonHolder = $( ' ' ).css( {			'border': '1px solid #a2a9b1',			'border-top': 'none',			'border-radius': '0 0 2px 2px',			'padding': '10px'		}).append( d.$element, f.$element, helpLink ); var $submitHolder = $( ' ' ) .css( 'overflow', 'hidden') .append( $(' ').css('display','block').text( 'By saving changes, you agree to our Terms of Use and agree to irrevocably release your text under the CC BY-SA 3.0 License and GFDL') ) .append( s.$element.css( 'float', 'right') ); return $( ' ' ) .addClass( 'jade-new' ) .append( 				' New judgement ', 				r.$element, 				$buttonHolder, 				$submitHolder 			); }	function isValidJudgement( textInput, damagingInput, faithInput ) { var textInput = textInput.getValue; var faithInput = faithInput.findSelectedItem; var damagingInput = damagingInput.findSelectedItem; // At least one bit of data must be present. if (			( textInput === '' || textInput === null ) &&			faithInput === null &&			damagingInput === null		) { return false; }

return { reason: textInput, // TODO: No ternary. goodfaith: ( faithInput === null ? null : faithInput.data === 'good faith' ), damaging: ( damagingInput === null ? null : damagingInput.data === 'damaging' ), user: $( "#pt-userpage a").text, ago: moment( Date.now ).fromNow };	}	function populateORES ( id, $ores ) { var uri = 'https://ores.wikimedia.org/v3/scores/enwiki?models=damaging%7Cgoodfaith&revids=' + id; $.ajax( uri ).done(function( dat ) {			var score = dat.enwiki.scores[id];			var j = {				'user': 'ORES' ,				'damaging': score.damaging.score.prediction,				'goodfaith': score.goodfaith.score.prediction			};			dPercent = Math.floor( score.damaging.score.probability[ score.damaging.score.prediction ] * 100 );			fPercent = Math.floor( score.goodfaith.score.probability[ score.goodfaith.score.prediction ] * 100 );			j.reason = "I am " + dPercent + "% sure about the damage, and " + fPercent + "% sure about the intention.";			$ores.append( getJudgementElement( j ) );		} ); }	/*	 * Given a revId create a judgement token *	 * @param {Number} id	 * @return {jQuery} **/	function getJudgementToken ( id, href ) { if ( 			// According to config, this rev won't have a judgement			!hasJudgement( id ) || 			// We couldn't find the diff page, so no judgement for this one			href.indexOf( 'oldid' ) < 0		) { return false; }		var text = config.singleJudgement ? 'Judgement' : getNoOfJudgements( id ) + ' judgement(s)'; return $( '' ) .addClass( 'judgement-token' ) .attr( 'href', href ) .css( {				'background': '#72777d',				'color': '#fff',				'padding': '3px',				'margin': '5px',				'border-radius': '2px'			} ) .text( text ) }	/*	 * Iterate over history items and add a judgement token **/	function addJudgementsToHistory { $( '#pagehistory li').each( function {			var $this = $( this );			var href = $this.find( '.mw-history-histlinks a' ).last.attr( 'href' );			var id = $this.attr( 'data-mw-revid');			var $judgementToken = getJudgementToken( id, href );			if ( $judgementToken ) {				$this.find( '.history-user' ).append( $judgementToken );			}		} ); }	/*	 * Iterate over changes items and add a judgement token **/	function addJudgementsToChanges { $( 'li.mw-changeslist-line').each( function {			var $this = $( this );			var href = $this.find( 'a' ).first.attr( 'href' );			var id = $this.attr( 'data-mw-revid');			var $judgementToken = getJudgementToken( id, href );			if ( $judgementToken ) {				$this.find( '.mw-usertoollinks' ).append( $judgementToken );			}		} ); }	/*	 * Dummy function that consistently tells how many judgements * a rev should have based on its ID	 * * @param {Number} id	 * @rutern {Number} Number of judgements **/	function getNoOfJudgements ( id ) { if ( !hasJudgement( id ) ) { return 0; }		if ( config.singleJudgement ) { return 1; }		if ( id.slice( -1 ) === '0' ) { return 1; } else { return parseInt( id.slice( -1 ) ); }	}	/* 	 * Dummy function that tells whether a rev should have * judgements or not, just to keep things random *	 * @param {Number} id	 * @return {Boolean} Whether this revision should have a judgement **/	function hasJudgement ( id ) { return id % 2 === 0; }	/* 	 * Detect which page we are on	 * Return false if we need not take any action *	 * @return {String|false} **/	function whichPage { if ( $( 'table.diff').length > 0 ) { return 'diff'; }		if ( $( '#pagehistory li ' ).length > 0 ) { return 'history'; }		if ( $( 'li.mw-changeslist-line' ).length > 0 ) { return 'change'; }		return false; }	// Dummy function returns a random generated judgement function getRandomJudgement ( userId ) { var randomReasons = [ "This is the deletion of a page on a local wiki. That can't be vandalism as it's something only a local admin can do. Maecenas ullamcorper quam a finibus consequat. Nunc et risus lorem. Sed pellentesque semper nibh, sed volutpat arcu pretium id. Cras auctor non libero id fermentum. Sed accumsan ornare elit eget pellentesque.", "Here I'm undoing bad edits. Maecenas ullamcorper quam a finibus consequat. Nunc et risus lorem. Sed pellentesque semper nibh, sed volutpat arcu pretium id. Cras auctor non libero id fermentum. Sed accumsan ornare elit eget pellentesque.", "This is just adding a sitelink, it doesn't look suspicious to me. Maecenas ullamcorper quam a finibus consequat. Nunc et risus lorem. Sed pellentesque semper nibh, sed volutpat arcu pretium id. Cras auctor non libero id fermentum. Sed accumsan ornare elit eget pellentesque.", "This is a bot fixing the way the value was entered. Maecenas ullamcorper quam a finibus consequat. Nunc et risus lorem. Sed pellentesque semper nibh, sed volutpat arcu pretium id. Cras auctor non libero id fermentum. Sed accumsan ornare elit eget pellentesque.", "Anonymous IPv6 user is adding a valid id for an external site. Nothing wrong with the addition. Maecenas ullamcorper quam a finibus consequat. Nunc et risus lorem. Sed pellentesque semper nibh, sed volutpat arcu pretium id. Cras auctor non libero id fermentum. Sed accumsan ornare elit eget pellentesque.", "This edit wasn't tagged, however can be considered vandalism. Maecenas ullamcorper quam a finibus consequat. Nunc et risus lorem. Sed pellentesque semper nibh, sed volutpat arcu pretium id. Cras auctor non libero id fermentum. Sed accumsan ornare elit eget pellentesque.", "It is a proper addition of a link. Maecenas ullamcorper quam a finibus consequat. Nunc et risus lorem. Sed pellentesque semper nibh, sed volutpat arcu pretium id. Cras auctor non libero id fermentum. Sed accumsan ornare elit eget pellentesque.", "Correction year of publication of a musical album by a registered user. Maecenas ullamcorper quam a finibus consequat. Nunc et risus lorem. Sed pellentesque semper nibh, sed volutpat arcu pretium id. Cras auctor non libero id fermentum. Sed accumsan ornare elit eget pellentesque.", "Typo noun correction from a registered user. Maecenas ullamcorper quam a finibus consequat. Nunc et risus lorem. Sed pellentesque semper nibh, sed volutpat arcu pretium id. Cras auctor non libero id fermentum. Sed accumsan ornare elit eget pellentesque.", "Modification of a word with a synonym by an anonymous user. Maecenas ullamcorper quam a finibus consequat. Nunc et risus lorem. Sed pellentesque semper nibh, sed volutpat arcu pretium id. Cras auctor non libero id fermentum. Sed accumsan ornare elit eget pellentesque.", "Rearrangement of comments by registered user. Maecenas ullamcorper quam a finibus consequat. Nunc et risus lorem. Sed pellentesque semper nibh, sed volutpat arcu pretium id. Cras auctor non libero id fermentum. Sed accumsan ornare elit eget pellentesque." ];		var randomUsers = [ 'halfak', 'aaron', 'EpochFail', 'adam', 'awight', 'prtksxna', 'prateek', 'foo', 'bar' ]; var goodfaith = ( Math.round( Math.random ) === 0 ) ? true : false; var damaging = ( Math.round( Math.random ) === 0 ) ? true : false; var reason = randomReasons[ Math.floor( Math.random * ( randomReasons.length - 1 ) ) ]; return { 'goodfaith': goodfaith, 'damaging': damaging, 'reason': reason, 'user': randomUsers[ userId ] };	} } );