Zum Inhalt springen

Benutzer:Christoph Jauera (WMDE)/gadget-test.js

aus Wikipedia, der freien Enzyklopädie
Dies ist eine alte Version dieser Seite, zuletzt bearbeitet am 2. April 2016 um 12:56 Uhr durch Christoph Jauera (WMDE) (Diskussion | Beiträge). Sie kann sich erheblich von der aktuellen Version unterscheiden.

Hinweis: Leere nach dem Veröffentlichen den Browser-Cache, um die Änderungen sehen zu können.

  • Firefox/Safari: Umschalttaste drücken und gleichzeitig Aktualisieren anklicken oder entweder Strg+F5 oder Strg+R (⌘+R auf dem Mac) drücken
  • Google Chrome: Umschalttaste+Strg+R (⌘+Umschalttaste+R auf dem Mac) drücken
  • Edge: Strg+F5 drücken oder Strg drücken und gleichzeitig Aktualisieren anklicken
// Page title
var gPageName = mw.config.get( 'wgPageName' );

// Gives us the most current revision ID for the page
var gCurRevisionId = mw.config.get( 'wgCurRevisionId' );

// Action: view/query/history
var gAction = mw.config.get( 'wgAction' );

// User name
var gUserName = mw.config.get( 'wgUserName' );

// The URL of the page, relative to DOCUMENT_ROOT
var gScript = mw.config.get( 'wgScript' );

// Revision ID of right revision on diff page
var gRightRevID = mw.config.get( 'wgRevisionId' );

// Revision ID of left revision on diff page
var gLeftRevID = mw.util.getParamValue( 'oldid' );

// Get value of diff param in URL
var gDiff = mw.util.getParamValue( 'diff' );

// Page ID
var gPageID = mw.config.get( 'wgArticleID' );

// Server
var gServer = mw.config.get( 'wgServer' );

// Function called when a tick on the slider is clicked
// Params: v1 - Left revision ID; v2 - Right revision ID
function refresh( v1, v2 ) {
	var $url = gServer + gScript + '?title=' + gPageName + '&diff=' + v2 + '&oldid=' + v1;
	location.href = $url;
}


// Formating date in JS
function formatDate( rawDate ) {
	var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'June', 'July', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec'];
	var f = new Date( rawDate );
	var fDate = f.getUTCDate();
	var fMonth = f.getUTCMonth();
	var fYear = f.getUTCFullYear();
	var fHours = ( '0' + f.getUTCHours()).slice(-2);
	var fMinutes = ( '0' + f.getUTCMinutes()).slice(-2);
	return ( fHours + ':' + fMinutes + ', ' + fDate + ' ' + months[fMonth] + ' ' + fYear ).toString();
}


// Setting the tick marks on the slider
// Params: element - jQuery slider; revs - revisions data from API
function setSliderTicks( element, revs ) {
	var $slider =  $( element ),
		max =  $slider.slider( "option", "max" ),
		min =  $slider.slider( "option", "min" ),
		spacing =  100 / ( max - min ),
		revData = getComposedRevData( revs ),
		maxChangeSizeLogged = Math.log( revData.maxChangeSize );
	for ( var i = 1; i <= max-min ; i++ ) {
		var diffSize = revs[i].size - revs[i-1].size,
			relativeChangeSize =  Math.ceil( 65.0 * Math.log( Math.abs( diffSize ) ) / maxChangeSizeLogged ) + 5,
			section = getSection( revs[i].comment ),
			html = '<b>' + formatDate( revs[i].timestamp ) + '</b><br>';

		html += mw.html.escape( revs[i].user ) + '<br>';
		if( revs[i].comment !== '' ) {
			html += '<br><i>' + mw.html.escape( revs[i].parsedcomment ) + '</i>';
		}
		html += '<br>' + diffSize + ' byte';
		$('<div class="ui-slider-tick-mark" title="<center>' +  html +'</center>"></div>')
			.css( {
				'left' : ( spacing * i - 0.75 ) + '%',
				'width' : spacing + '%',
				'height' : relativeChangeSize + 'px',
				'top' : diffSize > 0  ? '-' + relativeChangeSize + 'px' : 0,
				'background' : revData.sectionMap.get( section ) ? revData.sectionMap.get( section ) : 'black'
			} )
			.tipsy( {
				gravity: 's',
				html: true,
				fade: true
			} )
			.appendTo( $slider );
	}
}

function getComposedRevData( revs ) {
	var max = 0,
		changeSize = 0,
		section,
		sectionMap = new Map(),
		result;

	for ( i = 1; i < revs.length; i++) {
		changeSize =  Math.abs( revs[i].size - revs[i-1].size );
		section = getSection( revs[i].comment );
		if( changeSize > max ) {
			max = changeSize;
		}
		if( section.length > 0 && !sectionMap.has( section )) {
			sectionMap.set( section );
		}
	}

	var i = 0;
	sectionMap.forEach( function (item, key, sectionMap) {
		sectionMap.set( key, rainbow( sectionMap.size, i ) );
		i++;
	});

	for ( i = 0; i < sectionMap.length; i++) {
		sectionMap.set()
	}
	result = {
		maxChangeSize: max,
		sectionMap: sectionMap
	};

	return result;
}

function getSection( text ) {
	text = text.match(
		new RegExp(
			'(/\\* [^\\*]* \\*/)',
			'gi' ) );
	if( !text ) {
		return '';
	}
	return text[0].replace(
		new RegExp( ' \\*/|/\\* ', 'ig' ),
		'' );
}

// Adding the initial barebones slider
// Params: revs - revisions data from API; vals - initial positions for the slider handles
function addSlider( revs, vals ) {
	numberRevs = revs.length;
	var $slider = $( '<div class="range-slider"></div>' )
		.slider({
			range: true,
			min: 1,
			max: numberRevs,
			step: 1,
			animate: "fast",
			values: vals,
			create: function( event, ui ) {
				setSliderTicks( event.target, revs );
			},
			stop: function( event, ui ) {
				var v1 = revs[ui.values[0]-1].revid;
				var v2 = revs[ui.values[1]-1].revid;
				refresh( v1, v2 );
			},
			slide: function( event, ui ) {

			}
		});
	$( '.ui-slider-handle:first' ).attr( 'title', 'Huh' ).tipsy({ gravity: 's', html: true, fade: true });
	$html = $( '<td colspan="4" style="text-align:center;" class="slider"></td>' ).append( $slider );
	$html2 = $( '<tr>' ).append( $html );
	$legendHtml = $( '<td colspan="4" style="text-align:center; font-size: 0.7em"></td>' ).append( getSectionLegend( revs ) );
	$element = $( '.diff > tbody > tr' ).eq(0).after( $legendHtml );
	$element = $( '.diff > tbody > tr' ).eq(0).after( $html2 );
}

function getSectionLegend( revs ) {
	var revData = getComposedRevData( revs ),
		html = '';
	revData.sectionMap.forEach( function( item, key, sectionMap ) {
		html += '<span style="color:' + item + '; opacity: 0.25"> ■ </span>' + key + '';
	});
	return html;
}

// Function to find the initial positions of the slider handles
// Params: revs - revisions data from API
function findInitialValues( revs ) {
	var v1, v2, f1 = false, f2 = false, i;
	if ( gDiff == 'prev' ) {
		for ( i = 0; i < revs.length; i++) {
			if( revs[i].revid == gRightRevID ) {
				v2 = i+1;
				v1 = i;
				f1 = true;
				f2 = true;
				break;
			}
		}
	} else {
		for( i = 0; i < revs.length; i++ ) {
			if( revs[i].revid == gLeftRevID ) {
				v1 = i+1;
				f1 = true;
			}
		}
		for ( i = 0; i < revs.length; i++) {
			if( revs[i].revid == gRightRevID ) {
				v2 = i+1;
				f2 = true;
			}
		}
	}
	if( f1 === false || f2 === false ) {
		return false;
	}
	return [v1, v2];
}

// Driver function
mw.loader.using( ['jquery.ui.slider', 'jquery.ui.tooltip', 'jquery.tipsy'], function () {
	$( document ).ready( function() {
		$.ajax( {
			url: mw.util.wikiScript( 'api' ),
			data: {
				action: 'query',
				prop: 	'revisions',
				format: 'json',
				rvprop: 'ids|timestamp|user|comment|parsedcomment|size',
				titles: gPageName,
				formatversion:	2,
				rvstartid: gCurRevisionId,
				"continue": "",
				rvlimit: "120"
			},
			success: function( data ) {
				revs = data.query.pages[0].revisions;
				if ( !revs ) {
					return;
				}
				revs.reverse();
				vals = findInitialValues( revs );
				if( vals !== false ) {
					addSlider( revs, vals );
				}
			}
		} );
	} );
} );


// see http://stackoverflow.com/a/7419630/4782503
function rainbow( numOfSteps, step ) {
	// This function generates vibrant, "evenly spaced" colours (i.e. no clustering). This is ideal for creating easily distinguishable vibrant markers in Google Maps and other apps.
	// Adam Cole, 2011-Sept-14
	// HSV to RBG adapted from: http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
	var r, g, b;
	var h = step / numOfSteps;
	var i = ~~(h * 6);
	var f = h * 6 - i;
	var q = 1 - f;
	switch(i % 6){
		case 0: r = 1; g = f; b = 0; break;
		case 1: r = q; g = 1; b = 0; break;
		case 2: r = 0; g = 1; b = f; break;
		case 3: r = 0; g = q; b = 1; break;
		case 4: r = f; g = 0; b = 1; break;
		case 5: r = 1; g = 0; b = q; break;
	}
	var c = "#" + ("00" + (~ ~(r * 255)).toString(16)).slice(-2) + ("00" + (~ ~(g * 255)).toString(16)).slice(-2) + ("00" + (~ ~(b * 255)).toString(16)).slice(-2);
	return (c);
}