User:JJPMaster/vfdvote.js

From Uncyclopedia, the content-free encyclopedia
Jump to navigation Jump to search

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

  • Internet Explorer: hold down the Ctrl key and click the Refresh or Reload button, or press Ctrl+F5.
  • Firefox: hold down the Shift key while clicking Reload; alternatively press Ctrl+F5 or Ctrl-Shift-R.
  • Opera, Konqueror and Safari users can just click the Reload button.
  • Chrome: press Ctrl+F5 or Shift+F5
//<nowiki>

if ( document.location.href.match( 'Uncyclopedia:Votes_for_deletion' ) )
;(function( $ ){
	var cookieMeta = { expires: 10000, path: '/' },
	vfhLongSig = '~~~~',
	vfhShortSig = '~~~',
	api = mw.config.get( 'wgScriptPath' ) + '/api.php',
	index = mw.config.get( 'wgScript' );

	$.fn.isChecked = function( on ) {
		if ( on === false ) { return $( this ).removeAttr( 'checked' ); }
		else if ( on === true ) { return $( this ).attr( 'checked', 'checked' ); }
		else return !!$( this ).attr( 'checked' );
	}

	$.queryString = function( str ) {
		var arr = ( ( str || location.href ).match( /\?(.*)$/ ) || [ '', '' ] )[ 1 ].split( '&' ),
		  map = {};
		for ( var i = 0; i < arr.length; i ++ ) {
			var pair = arr[ i ].split( '=' );
			map[ pair[ 0 ] ] = decodeURIComponent( pair[ 1 ] );
		}
		return map;
	}

	function bool( str ) {
		return String( str ).match( /true/i ) ? true : false;
	}

	function fetch( article, done, fail, always ) {
		return $.get( api, {
			'action': 'query',
			'titles': article,
			'prop': 'revisions|info',
			'rvprop': 'content',
			'rvlimit': 1,
			'intoken': 'edit',
			'format': 'xml'
		})
			.done( done )
			.fail( fail )
			.always( always )
	}

	function save( title, text, summary, token, done, fail, always ) {
		return $.post( api, {
			'action': 'edit',
			'format': 'xml',
			'text': text,
			'title': title,
			'token': token,
			'summary': summary
		})
			.done( done )
			.fail( fail )
			.always( always )
	}

	function createBox( vfhPage, qs ) {
		//private functions
		function changeVote() {
			var useT = vBox.find( '.input-vfhtemp' ).isChecked(),
			  delim = ( useT ) ? [ '{{', '}} ' ] : [ "'''", "'''. " ],
			  choice = vBox.find( '.select-vfhtype' ).val(),
			  vote = delim.join( choice ),
			  text = comment();
			if ( text )
				comment( useT ? templateReplace( text, vote + '$2' ) : boldTextReplace( text, vote ) );
			else comment( vote );
			vBox.removeClass( 'For Against Comment' ).addClass( choice );
		}

		function comment( str ) {
			var field = vBox.find( '.vfhcomment' );
			if ( str ) field.focus().val( str );
			return field.val();
		}

		function bigComment( e ) {
			$( '<textarea>', { 'class': 'vfhcomment' } )
				.appendTo( vBox.find( '.chukka' ) )
				.focus()
				.val( $( this ).remove().val() )
				.animate( { height: '50px' } );
		}

		function templateReplace( str1, str2 ) {
			return str1.replace( /^{{(For|Against|Comment)\|*([^}]*)}} */i, str2 );
		}

		function boldTextReplace( str1, str2 ) {
			return str1.replace( /^'''(For|Against|Comment)'''\.* */i, str2 );
		}

		function templates() {
			var useT = $( this ).isChecked();
			$.cookie( 'vfh_use_template', useT, cookieMeta );
			if ( !useT ) comment( templateReplace( comment(), "'''$1'''. $2" ) )
			else comment( boldTextReplace( comment(), '{{$1}} ' ) );
		}

		function tildes() {
			var use3 = $( this ).isChecked();
			$.cookie( 'vfh_use_shortsig', use3, cookieMeta );
			vBox.find( '.span-vfhsig' ).text( use3 ? vfhShortSig : vfhLongSig );
		}

		function disableBox( e ) {
			var $t = $( this );
			if ( $t.isChecked() && confirm( 'Turn off the VFH widget? To turn it back on, you will need to clear your cookies for this site.' ) ) {
				$.cookie( 'vfh_widget_disabled', true, cookieMeta );
				vBox.hide(); //vBox refers to the particluar vBox within the scope of the outer function
			}
			else $t.isChecked( false );
		}

		function getVoteContents() {
			var str = comment(),
			  sig = vBox.find( '.span-vfhsig' ).text(),
			  type = vBox.find( '.select-vfhtype' ).val().toLowerCase()
			return {
				type: type,
				comment: str,
				sig: sig,
				text: $.trim( str ) + ' ' + sig,
				novote: !type,
				quantity: !!window.wgUserName ? 1 : 0.5
			}
		}

		function onSubmit( e ) {
			e.preventDefault();
			userVote = getVoteContents();
			if ( userVote.novote ) {
				alert( 'Yo, choose a vote first! How else am I gonna know where to put it?' );
				return false;
			};
			vBox.text( 'Saving vote...' );
			fetch( vfhPage )
				.done( saveVotePage )
				.fail( fetchError );
		}

		function saveVotePage( xml ) {
			var token = $( xml ).find( 'page' ).attr( 'edittoken' ),
			  text = parse( $( xml ).find( 'rev' ).text(), userVote );
			if ( !text ) return readError();
			save( vfhPage, text, userVote.summary, token )
				.done( onSave )
				.fail( saveError );
		}

		function parse( str, userVote ) {
			  //FUCKING EXPLICIT CASTINGS TO FLOATING POINT NUMBERS! HOW DO THEY WORK?
			var votes = +( new RegExp( userVote.type + 'number=([^|]*)', 'i' ).exec( str ) || [ '','' ] )[ 1 ] + userVote.quantity;
			switch ( userVote.type ) {
				case 'for':
					str = str.replace( /(\|againstnumber)/i, '#' + userVote.text + '\n$1' )
						.replace( /(\|fornumber=)[^|]*/i, '$1' + votes + '\n' );
					userVote.summary = '[[UN:AES|←]]Voted for';
					break;
				case 'against':
					str = str.replace( /(\|comments)/i, '#' + userVote.text + '\n$1' )
						.replace( /(\|againstnumber=)[^|]*/i, '$1' + votes + '\n' );
					userVote.summary = '[[UN:AES|←]]Voted against';
					break;
				case 'comment':
					str = str.replace( /(\n}})/, '\n*' + userVote.text + '$1' );
					userVote.summary = '[[UN:AES|←]]Comment';
					break;
				default:
					return null;
			};
			return str;
		}

		function onSave( xml ) {
			if ( qs )
				if ( ! $( xml ).find( 'error' ).length )
					vBox.html( $( '<div>' )
						.text( 'Vote saved! [ ' )
						.append( $( '<a>', { href: mw.util.wikiUrlencode( '/wiki/Uncyclopedia:VFH/' + qs ), text: 'go to nomination' } ) )
						.append( ' ]' )
						.append( closeBtn() )
						)
				else saveError();
			else
				$.get( index + '?action=render&title=' + vfhPage )
					.done( function( data ) { $( '#bodyContent' ).html( data ); });
		}

		function readError() {
			error( 'Could not read vote page!' );
		}

		function saveError() {
			error( 'There was an error saving your vote.' );
		}

		function fetchError() {
			error( 'There was an error retrieving the vote page.' );
		}

		function error( str ) {
			vBox.text( str ).append( closeBtn() );
		}

		function closeBtn( overrideCallback ) {
			return $( '<span>', {
				text: '[ x ]',
				'class': 'link span-vfhclose',
				title: 'close',
				click: overrideCallback || function() { vBox.hide(); } //closure
			});
		}

		var vBox, form, controls, voteArea, options, userVote, changeDone;
		vBox = $( '<div>', { 'class': 'div-vfhbox' } );
		form = $( '<form>', {
			'class': 'form-vfh',
			action: '',
			submit: onSubmit
		})
			.appendTo( vBox );

		controls = $( '<div>', { 'class': 'div-vfhcontrols' } )
			.append( $( '<span>', {
				text: '[ ? ]',
				'class': 'link span-vfhoption',
				title: 'options',
				click: function() { options.fadeToggle() }
			}) )
			.append( closeBtn() )
			.appendTo( form );

		voteArea = $( '<div>', {
			'class': 'div-vfhcomponents',
			append: $( '<a>', { href: '/wiki/Uncyclopedia:VFH', text: 'Vote on this article!' } )
		})
			.appendTo( form );
		$( '<select>', {
			'class': 'select-vfhtype',
			change: changeVote
		})
			.append( $( '<option>', { value: '', text: '---vote---', selected: 'selected', disabled: 'disabled' } ) )
			.append( $( '<option>For</option>' ) )
			.append( $( '<option>Against</option>' ) )
			.append( $( '<option>Comment</option>' ) )
			.appendTo( voteArea );
		$( '<input>', {
			'class': 'vfhcomment',
			keyup: bigComment,
			click: bigComment
		})
			.appendTo( voteArea );
		$( '<span>', {
			'class': 'span-vfhsig',
			text: bool( $.cookie( 'vfh_use_shortsig' ) ) ? vfhShortSig : vfhLongSig
		})
			.appendTo( voteArea );
		$( '<input>', {
			'class': 'submit-vfh',
			type: 'submit',
			val: 'Vote'
		})
			.appendTo( voteArea );

		$( '<div>', { 'class': 'chukka' } ).appendTo( form );

		options = $( '<div>', { 'class': 'div-vfhoptions' } ).appendTo( form );
		$( '<label>Use vote templates</label>' )
			.append( $( '<input>', {
				type: 'checkbox',
				'class': 'input-vfhtemp',
				change: templates,
				//if user has not explicitly chosen to not use templates, use templates.
				isChecked: !$.cookie( 'vfh_use_template' ) ? true : bool( $.cookie( 'vfh_use_template' ) )
			}) )
			.appendTo( options );
		$( '<label>Use 3 tildes in sig</label>' )
			.append( $( '<input>', {
				type: 'checkbox',
				'class': 'input-vfhsig',
				change: tildes,
				isChecked: bool( $.cookie( 'vfh_use_shortsig' ) )
			}) )
			.appendTo( options );
		$( '<label>Disable this thing</label>' )
			.append( $( '<input>', {
				type: 'checkbox',
				'class': 'input-vfhoff',
				change: disableBox,
				isChecked: bool( $.cookie( 'vfh_disable_widget' ) )
			}) )
			.appendTo( options );
		return vBox;
	}

	function init() {
		if ( bool( $.cookie( 'vfh_widget_disabled' ) ) || $( '#old-forum-warning' ).length ) return;
		var isVFH = !!$( '#isvfhpage' ).length,
		  isVotePage = !!$( '#isvfhvotepage' ).length,
		  qs = $.queryString().vfhlink,
		  vfhPage = isVotePage ? wgPageName : qs ? 'Uncyclopedia:VFH/' + qs : null;
		if ( isVFH || isVotePage ) {
			$( '.vfharticlelink a' ).each( function(){
				var $this = $( this );
				var vpage = $this.attr( 'href' ) + '?vfhlink=' + encodeURIComponent( $this.parent().attr( 'title' ).replace( / /g, '_' ).match( /\VFH\/(.+$)/i )[ 1 ] )
				$this.attr( 'href', vpage );
			});
		}
		if ( isVotePage || qs ) {
			createBox( vfhPage, qs )
				//.css( 'position', qs ? 'fixed' : 'relative' ) //this seems unnecessary, could be handled with css
				.appendTo( isVotePage ? '#isvfhvotepage' : '#bodyContent' );
		}
	}

	$( document ).ready( init );
})( jQuery );
//</nowiki>