User:Jeblad/trending/script.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.
// Code to make a notice about verfiabillity
// © John Erling Blad, Creative Commons by Attribution 3.0

// this needs slight editing if used as a gadget,
// ie. remove first and last line and make a line in [[MediaWiki:Gadgets-definition]]
mw.loader.using( ['mediawiki.api','mediawiki.Title'], function () {
mw.hook( 'wikipage.content' ).add(function( $content ) {
	"use strict";
	var conf = mw.config.get( [
		'wgUserLanguage',
		'wgNamespaceNumber',
		'wgCanonicalSpecialPageName',
		'wgServerName',
		'wgArticlePath'
	] );
	// should be a special page
	if ( conf.wgNamespaceNumber != -1) {
		mw.log( 'not a special page, terminates' );
		return;
	}
	// should be the statistics page
	if ( conf.wgCanonicalSpecialPageName != 'Statistics') {
		mw.log( 'not the Statistics page, terminates' );
		return;
	}
	var containers = [];
	var $container = mw.util.$content.find('#mw-content-text');
	
	// build the container for the toc line
	var $statstoc = $('<ul>')
		.attr({
			'id':'statstoc',
			'role':'tablist'
		})
		.prependTo($container);
	
	// register the statstbl
	var $statstbl = mw.util.$content.find('.mw-statistics-table');
	$statstbl
		.each(function(i, elem){
			containers.push($(elem));
		})
		.first()
		.attr({
			'id': 'mw-statsection-general'
		});
	
	// build the toplist skeleton
	var $toplist = $('<table>')
		.attr({
			'id':'mw-statsection-toplist',
			'class':'wikitable mw-statistics-table sortable',
			'style':'display:none'
		});
	var $thead = $('<thead>').appendTo($toplist);
	var $tbody = $('<tbody>').appendTo($toplist);
	$toplist.insertAfter($statstbl);
	containers.push($toplist);
	
	var buildTab = function(id, text) {
		var $tab = $('<li>')
		.attr({'role':'presentation'});
		var $link = $('<a>')
		.attr({
			'tabindex': -1,
			'aria-selected': false,
			'aria-controls': 'mw-statsection-'+id,
			'href': '#mw-statsection-'+id,
			'role': 'tab',
			'id': 'statstab-'+id
		})
		.text(text)
		.appendTo($tab)
		.click(function(){
			mw.log('hide');
			for (var i=0, l=containers.length; i<l; i++) {
				containers[i].slideUp('slow');
			}
			return false;
		});
		return $tab;
	};

	var ajax = {
		'protocol': mw.Uri.protocol,
		'host': 'wikimedia.org',
		'path': '/api/rest_v1/metrics/pageviews/top'
	};
	
	var buildLocalLink = function(path, title, page) {
		if (page === undefined) {
			page = title;
		}
		mw.log('href '+path.replace('$1', page.replace(/\s/g, '_')));
		mw.log('cont '+title.replace(/_/g, ' '));
		return $('<a>')
			.attr({
				'href':path.replace('$1', page.replace(/\s/g, '_'))
			})
			.text(title.replace(/_/g, ' '));
	};
	
	var buildURI = function(ajax, opts) {
		var args = jQuery.extend({}, ajax, opts);
		var path = ajax.path.split('/');
		if (args.project === undefined) {
			args.project = conf.wgServerName;
		}
		if (/^[\w\.]*$/.test(args.project)) path.push(args.project);
		if (args.access === undefined) {
			args.access = 'all-access';
		}
		if (/^[-\w]*$/.test(args.access)) path.push(args.access);
		var now = new Date();
		var yesterday = new Date(now.valueOf()-24*60*60*1000);
		if (args.year === undefined) {
			args.year = yesterday.getUTCFullYear(); 
		}
		if (typeof args.year === 'number') path.push(''+args.year);
		if (args.month === undefined) {
			args.month = yesterday.getUTCMonth()+1; 
		}
		if (typeof args.month === 'number') path.push((args.month<10 ? '0' : '')+args.month);
		if (args.day === undefined) {
			args.day = yesterday.getUTCDate(); 
		}
		if (typeof args.day === 'number') path.push((args.day<10 ? '0' : '')+args.day);
		return new mw.Uri( jQuery.extend({}, ajax, { 'path': path.join('/')}) );
	};
	
	var fetchStats = function(uri, context) {
		mw.log('fetch stats');
		var jqxhr = $.ajax({
			'cache':true,
			'context': context,
			'dataType': 'json',
			'url': uri })
		.done(function(data) {
			mw.log('got data');
			if (data.items && data.items[0]) {
				mw.log('got items');
			if (data.items[0].articles) {
				mw.log('got articles');
				var articles = data.items[0].articles;
				for (var i=0,l=articles.length; i<l; i++) {
					$('<tr>')
						.append($('<td>').append(buildLocalLink(conf.wgArticlePath, articles[i].article)))
						.append($('<td>').attr({'class': 'mw-statistics-numbers'}).text(articles[i].views))
						.append($('<td>').attr({'class': 'mw-statistics-numbers'}).text(''))
						.append($('<td>').attr({'class': 'mw-statistics-numbers'}).text(articles[i].rank))
						.append($('<td>').attr({'class': 'mw-statistics-numbers'}).text(''))
						.appendTo($tbody);
				}
			}}
		});
	};
	var fetchToplist = function(opts) {
		fetchStats(buildURI(ajax, opts));
	};
	// set up localized messages and some templates
	var msgs = [
		'statistics-general-tab',
		'statistics-toplist-tab',
		'statistics-toplist-title',
		'statistics-toplist-page',
		'statistics-toplist-article',
		'statistics-toplist-views',
		'statistics-toplist-rank',
		'statistics-toplist-views-value',
		'statistics-toplist-views-change',
		'statistics-toplist-rank-value',
		'statistics-toplist-rank-change'
	];
	var api = new mw.Api();
	var amRequest = api.ajax({
		action: 'query',
		meta: 'allmessages',
		amlang: conf.wgUserLanguage,
		ammessages: msgs
	});
	mw.hook( 'wikipage.content' ).add(function( $content ) {
		amRequest.then(function(data){
			$.each( data.query.allmessages, function ( index, message ) {
				if ( message.missing !== '' ) {
					mw.messages.set( message.name, message['*'] );
				}
			});
			
			// set up the general tab
			var $generalTab = buildTab('general', mw.message( 'statistics-general-tab' ).plain())
				.toggleClass('selected')
				.appendTo($statstoc);
			$generalTab.find('a')
				.click(function(){
					$('#statstoc').children('li').removeClass('selected');
					$(this).parent().addClass('selected');
					$('#mw-statsection-general').slideDown('slow');
					return false;
				});
			
			// set up the toplist tab
			var $toplistTab = buildTab('toplist', mw.message( 'statistics-toplist-tab' ).plain())
				.appendTo($statstoc);
			$toplistTab.find('a')
				.click(function(){
					$('#statstoc').children('li').removeClass('selected');
					$(this).parent().addClass('selected');
					$('#mw-statsection-toplist').slideDown('slow');
					fetchToplist({});
					return false;
				});
			
			// controller
			//var controller = $('<div>').text('Controller');
			
			// set up toplist table headers
			$toplist.find('thead')
				.append($('<tr>')
					.append($('<th>')
						.attr({'colspan':5})
						.append(buildLocalLink(
							conf.wgArticlePath,
							mw.message( 'statistics-toplist-title' ).plain(),
							mw.message( 'statistics-toplist-page' ).plain()))))
				.append($('<tr>')
					.append($('<th>').attr({'rowspan':2}).text(mw.message( 'statistics-toplist-article' ).plain()))
					.append($('<th>').attr({'colspan':2}).text(mw.message( 'statistics-toplist-views' ).plain()))
					.append($('<th>').attr({'colspan':2}).text(mw.message( 'statistics-toplist-rank' ).plain())))
				.append($('<tr>')
					.append($('<th>').text(mw.message( 'statistics-toplist-views-value' ).plain()))
					.append($('<th>').text(mw.message( 'statistics-toplist-views-change' ).plain()))
					.append($('<th>').text(mw.message( 'statistics-toplist-rank-value' ).plain()))
					.append($('<th>').text(mw.message( 'statistics-toplist-rank-change' ).plain())));
		});
	});
});
});