MediaWiki:Gadget-work-in-progress.js

Fra Wikipedia, den frie encyklopedi

Merk: Etter publisering vil det kanskje være nødvendig å slette mellomlageret i nettleseren din for å se endringene.

  • Firefox / Safari: Hold Shift mens du klikker på Oppdater, eller trykk enten Ctrl+F5 eller Ctrl+R (⌘+R på Mac)
  • Google Chrome: Trykk Ctrl+Shift+R (⌘+Shift+R på Mac)
  • Internet Explorer / Edge: Hold Ctrl mens du trykker på Oppdater eller trykk Ctrl+F5
  • Opera: Ttrykk Ctrl+F5.
// Code for adding a more visible warning about on-going editing
// © John Erling Blad, Creative Commons by Attribution 3.0
$( function (){
	"use strict";
	var safeTimespan = 1*24*60*60*1000;
	var checkTimespan = 3*24*60*60*1000;
	var sizeLimit = 100;
	var limitLargeEdits = 2;
	var limitSmallEdits = 5;
	var conf = mw.config.get( [
		'wgTitle',
		'wgArticleId',
		'wgUserId',
		'wgUserLanguage',
		'wgAction',
		'wgNamespaceNumber',
		'wgContentNamespaces',
		'wgIsProbablyEditable',
		'wgIsArticle',
	] );
	var monthNamesShort = [ '', 'jan.', 'feb.', 'mar.', 'apr.', 'mai', 'jun.', 'jul.', 'aug.', 'sep.', 'okt.', 'nov.', 'des.' ];
	// should be an editable article
	// a blocked user will not be allowed to edit the article
	if ( !conf.wgIsArticle || !conf.wgIsProbablyEditable ) {
		return;
	}
	// should be in a content namespace
	if ( conf.wgContentNamespaces.indexOf( conf.wgNamespaceNumber ) < 0 ) {
		return;
	}
	// should only be shown during view
	if ( conf.wgAction !== "view" ) {
		return;
	}
	// extract the string with the last mod dtg
	var lastEdited = $( '#footer-info-lastmod' ).text();
	if ( lastEdited === undefined ) {
		return;
	}
	// extract the dtg from the last mod string
	var matches = lastEdited.match( /(\d+)\.\s+([\w\.]+)\s+(\d\d\d\d)\D+((\d+):(\d+)(:(\d+))?)/ );
	if ( matches === undefined || matches === null || matches.length <= 5 ) {
		mw.log( 'did not find a match' );
		return;
	}
	// calculate the dtgs and the associated limits
	var month = monthNamesShort.indexOf( matches[2].toLowerCase() );
	if (month === undefined) {
		mw.log( 'did not find a month' );
		return;
	}
	var editedAtDTG = matches[3]+'-'+month+'-'+matches[1]+'T'+matches[4];
	var editedAtTS = Date.parse( editedAtDTG );
	var nowTS = Date.now();
	var checkFromDate = new Date();
	var elapsedTimespan = nowTS - editedAtTS;
	// should be within the limits before we do further checks
	if ( elapsedTimespan > safeTimespan ) {
		mw.log( 'will be lost, in time, like [chokes up] tears… in… rain. Time… to die' );
		return;
	}
	// check if there is other work in progress templates
	if ($('#mw-content-text').find('.workinprogress').length > 0) {
		mw.log( 'already has a work-in-progress template' );
		return;
	}
	// get the revisions for further checks
	var api = new mw.Api();
	api.ajax({
		action: 'query',
		format: 'json',
		titles: conf.wgTitle,
		prop: 'revisions',
		rvlimit: 20, // don't bother with continue
		rvprop: ['timestamp', 'userid', 'size', 'sha1'],
		rvdir: 'older',
		rvstart: 'now'
	})
	.then(function(data) {
		// log good
		mw.log('good: '+conf.wgTitle);
		var page = data.query.pages[conf.wgArticleId];
		if (page !== undefined) {
			var revision, i, l;
			// find all sha1s
			var sha1s = {};
			for (i=0,l=page.revisions.length;i<l;i++) {
				revision = page.revisions[i];
				if (sha1s[revision.sha1] === undefined) {
					sha1s[revision.sha1] = 0;
				}
				sha1s[revision.sha1]++;
			}
			// mark all old and anonymous revisions
			for (i=0,l=page.revisions.length;i<l;i++) {
				revision = page.revisions[i];
				revision.invalid = 0;
				if (nowTS-Date.parse(revision.timestamp) > checkTimespan) {
					revision.invalid++;
				}
				if (revision.userid === 0) {
					revision.invalid++;
				}
			}
			// mark all reverted revisions
			for (var sha1 in sha1s) {
				if (sha1 > 1) {
					continue;
				}
				var found = false;
				for (i=0,l=page.revisions.length;i<l;i++) {
					revision = page.revisions[i];
					if (sha1s[revision.sha1] > 1) {
						revision.invalid++;
					}
					if (revision.sha1 === sha1) {
						sha1s[revision.sha1]--;
					}
				}
			}
			// check for less than a few large edits
			var numLarge = 0;
			var previous = page.revisions[0];
			for (i=0,l=page.revisions.length;i<l;i++) {
				revision = page.revisions[i];
				if (revision.invalid > 0) {
					continue;
				}
				var diff = previous.size - revision.size;
				if (diff > sizeLimit) {
					numLarge++;
				}
				previous = revision;
			}
			if (numLarge<limitLargeEdits) {
				mw.log( 'too few large edits: '+conf.wgTitle );
				return;
			}
			// count occuring users
			var users = {};
			for (i=0,l=page.revisions.length;i<l;i++) {
				revision = page.revisions[i];
				if (revision.invalid > 0) {
					continue;
				}
				if (users[revision.userid] === undefined) {
					users[revision.userid] = 0;
				}
				users[revision.userid]++;
			}
			// check if this user has previously occured
			if (users[conf.wgUserId] !== undefined) {
				mw.log( 'user has previous edits: '+conf.wgTitle );
				return;
			}
			// check if any user has edited more than a few times
			var numSmall = 0;
			for (var num in users) {
				if (num > limitSmallEdits) {
					numSmall++;
				}
			}
			if (numSmall===0) {
				mw.log( 'too few small edits: '+conf.wgTitle );
				return;
			}
		}
		// still around, register our previously found string as a message
		mw.messages.set({ 'maintenance-workinprogress-last-edited': lastEdited });
		// get additional messages
		api.ajax({
			action: 'query',
			meta: 'allmessages',
			amlang: mw.config.get( 'wgUserLanguage' ),
			ammessages: [
				'maintenance-workinprogress-title'
			]
		})
		.then(function(data){
			// procede and create the warning
			mw.log( 'build the warning: '+conf.wgTitle );
			$.each( data.query.allmessages, function ( index, message ) {
				if ( message.missing !== '' ) {
					mw.messages.set( message.name, message['*'] );
				}
			});
			mw.notify(
				mw.message( 'maintenance-workinprogress-last-edited' ).escaped(),
				{
					title:mw.message( 'maintenance-workinprogress-title' ).escaped(),
					tag: 'work-in-progress'
				}
			);
		});
	})
	.fail(function(jqXHR, textStatus, errorThrown) {
		// log and die silently
		mw.log('fail: '+conf.wgTitle);
		return;
	});
});