MediaWiki:Gadget-PageWatcher.js

Aus Wikiversity

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
  • Internet Explorer/Edge: Strg+F5 drücken oder Strg drücken und gleichzeitig Aktualisieren anklicken
  • Opera: Strg+F5
// Version 0.32 - Anpassung an "modern"-Skin
// Version 0.31 - Rücknahme der Version 0.3 (faktisch also Version 0.2), da
//               in Version 0.3 nun jedesmal die "Aboliste" sichtbar editiert wird.
// Version 0.3 - Besserer Schutz der Privatsphäre durch Vermeidung der
//              Übertragung des PageWatcher-Cookies zum Server bei jedem Seitenaufruf.
// Version 0.2 - Schutz der Privatsphäre durch Verwendung von Cookies
//             (mit fallback: [[MediaWiki:PageWatcher-File]])
// Version 0.1
// (c) 2008 by Exxu
// Released under GPL or CC-by-SA 2.5 (http://creativecommons.org/licenses/by-sa/2.5/deed.de)
// at your choice
//******************************************************************************************
// Änderungsüberwachung für Einträge in der "Aboliste" ([[MediaWiki:PageWatcher-File]]).
// Es wird jeder Eintrag der Form:
// [[Lemma_des_interessierenden_Artikels]]
// berücksichtigt. Ausgeschlossen werden derartige Links auf Spezialseiten, Kategorien,
// und die eigene oder fremde Abolisten.
// Nach Änderungen wird der Nutzer durch eine Meldung auf der aktuellen Seite informiert,
// wenn eine Seite zum Ansehen aufgerufen wird. Ausnahmen bilden hiervon Spezialseiten,
// die Aboliste und der Aufruf irgendeiner Seite zum Bearbeiten.
// Insoweit wird die Meldung verzögert.
//******************************************************************************************
// Verwendete MediaWiki-Dateien:
// [[MediaWiki:PageWatcher-File]] - Lemma der Aboliste (ohne "/");
//      Diese sollte auf ".js" enden, weil dadurch nur der Eigentümer (oder ein Admin)
//      Änderungen durchführen kann. Diese Datei wird im Benutzernamensraum erwartet.
//      Beispiel: Benutzer:Anonymous/Aboliste.js.
//    Fehlt diese Datei wird "WatchFile.js" angenommen.
// [[MediaWiki:PageWatcher-Summary]] - Zusammenfassungstext für automatische Edits
//    Fehlt diese Datei, wird "Updates" angenommen
// [[MediaWiki:PageWatcher-Updates]] - Text für die Benutzerinformation bei Änderungen
//    Fehlt diese Datei, wird "There are updates for files you are watching" angenommen.
//******************************************************************************************
// Verwendete Javascript-Variablen:
// wgAction, wgCanonicalName,wgServer, wgScript, wgUserName,
//******************************************************************************************
var PageWatcher = {
	_msgUpdated: null,
	_watchfile: null,
	_msgSummary: null,
	_myDate: null,
	_HTTPReqObj: {
		_HRO: null,
		call: function( method, uri, async, callback, options ) {
			PageWatcher._HRO = ( !PageWatcher._HRO && typeof sajax_init_object == 'function' ) ? sajax_init_object() : PageWatcher._HRO;
			if( !PageWatcher._HRO ) {
				if( window.XMLHttpRequest ) {
					PageWatcher._HRO = new XMLHttpRequest();
				} else {
					try {
						PageWatcher._HRO = new ActiveXObject( 'Msxml2.XMLHTTP' );
					} catch( e ) {
						try {
							PageWatcher._HRO = new ActiveXObject( 'Microsoft.XMLHTTP' );
						} catch( e ) {
						}
					}
				}
			}
			if( PageWatcher._HRO ) {
				PageWatcher._HRO.open( method, uri, async );
				if ( options && options.headers ) {
					for ( key in options.headers ) {
						PageWatcher._HRO.setRequestHeader( key, options.headers[key] );
					}
				}
				PageWatcher._HRO.onreadystatechange = ( callback ) ? callback : null;
				PageWatcher._HRO.send( ( options && options['data'] ) ? options['data'] : null );
			}
			return PageWatcher._HRO;
		}
	},

	_editAboList: function( links ) {
		var request = PageWatcher._get( 'User:' + mw.config.get('wgUserName') + PageWatcher._watchfile, 'edit' );
		if( !request || request.status >= 400 ) {
			return false;
		}
		var div = document.createElement( 'div' );
		div.innerHTML = request.responseText;
		var form = div.getElementsByTagName( 'form' );
		if ( typeof form == 'undefined' || form.length < 1 ) {
			return false;
		}
		form = form[0];
		var content = form.getElementsByTagName( 'textarea' );
		if ( typeof content == 'undefined' || content.length < 1 ) {
			return false;
		}
		return PageWatcher._postData( form, links );
	},

	_extractLinks: function( text ) {
		var links = {};
		var regexp = /\[\[([^\|\]]+)[\|\]][^\]]*\]([^\d\*]*(\d[^\n$]*))?[\n$]?/g;
		while ( regx = regexp.exec( text ) ) { // Überwachungslinks extrahieren
			if(
				regx[1].match( /^Spe[cz]ial:/i ) || // Spezialseiten ausschließen
				regx[1].match( /^[CK]ategor[iy]e?:/i ) || // Kategorielinks ausschließen
				regx[1].indexOf( PageWatcher._watchfile ) > 0 // Aboliste ausschließen
			)
			{
				continue;
			}
			links[regx[1].replace( / /g, '_' )] = regx[3];
		};
		return links;
	},

	_formatLinks: function( links ) {
		data = '';
		for ( key in links ) {
			data += PageWatcher._myEncodeURIComponent(
				'* [[' + key.replace( /_/g, ' ' ) + ']] ' + links[key] + "\n"
			);
		}
		return data;
	},

	/* Read some file by given action. If cached equals to false, read it from server */
	_get: function( file, action, cached ) {
		return PageWatcher._HTTPReqObj.call(
			'GET',
			mw.config.get('wgServer') + mw.config.get('wgScript') + '?title=' + file + '&action=' + action +
				( !cached ? '&' + PageWatcher._myDate.getTime() : '' ),
			false
		);
	},

	/* Read content of MediaWiki-Files perhaps from the browser's cache */
	_getText: function( msg, file, val ) {
		if ( !msg ) {
			request = PageWatcher._get( file, 'raw', true );
			return ( ( !request || request.status >= 400 ) ? val : request.responseText );
		} else {
			return msg;
		}
	},

	_hasCookies: function() {
		return document.cookie && document.cookie.indexOf( 'PageWatcher=' ) == 0;
	},

	_lastModified: function( lemma ) {
		var request = PageWatcher._get( lemma, 'history' );
		if ( !request || request.status >= 400 || !request.responseText ) {
			return null;
		}
		var div = document.createElement( 'div' );
		div.innerHTML = request.responseText;
		var ul = div.getElementsByTagName( 'ul' );
		var lastversion = null;
		for ( i = 0; i < ul.length; i++ ) {
			if ( ul[i].getAttribute( 'id' ) == 'pagehistory' ) {
				lastversion = ul[i];
				break;
			}
		}
		if ( !lastversion ) {
			return null;
		}
		var anchors = lastversion.getElementsByTagName( 'li' )[0].getElementsByTagName( 'a' );
		if( typeof anchors == 'undefined' ) {
			return null;
		}
		for ( i = 0; i < anchors.length; i++ ) {
			if( !anchors[i].firstChild.nodeValue.match( /(\d\d:\d\d,.+\d\d\d\d)/ ) ) {
				continue;
			}
			return RegExp.$1;
		}
		return null;
	},

	_myEncodeURIComponent: function( val ) {
		val = val.replace( /\&lt;/gi, '<' );
		val = val.replace( /\&gt;/gi, '>' );
		val = val.replace( /\&quot;/gi, '"' );
		val = val.replace( /\&amp;/gi, '&' );
		return encodeURIComponent( val );
	},

	_postData: function( form, links ) {
		PageWatcher._msgSummary = PageWatcher._getText(
			PageWatcher._msgSummary,
			'MediaWiki:PageWatcher-Summary',
			'Updates'
		);
		var data = '';
		var inputFields = form.getElementsByTagName( 'input' );
		for ( var i = 0; i < inputFields.length; i++ ) {
			if ( inputFields[i].type == 'submit' && inputFields[i].name != 'wpSave' ) {
				continue;
			}
			data += '&' + inputFields[i].name;
			data +=	( inputFields[i].name == 'wpMinoredit' ) ? '=1' :
				( inputFields[i].name == 'wpWatchthis' ) ? '=1' :
				( inputFields[i].name == 'wpSummary' ) ? '=' + PageWatcher._msgSummary :
				'=' + PageWatcher._myEncodeURIComponent( inputFields[i].value );
		}
		data += '&wpTextbox1=' + PageWatcher._formatLinks( links );
		return PageWatcher._HTTPReqObj.call(
			'POST',
			form.action,
			false,
			null,
			{
				'data': data,
				'headers': {
					'Content-Type': 'application/x-www-form-urlencoded',
					'Referer': mw.config.get('wgServer') + mw.config.get('wgScript') + '?title=User:' + mw.config.get('wgUserName') + PageWatcher._watchfile + '&action=edit'
				}
			}
		);
	},

	_setCookies: function( links ) {
		var futdate = new Date(); // Get the current time and date
		var expdate = futdate.getTime(); // Get the milliseconds since Jan 1, 1970
		expdate += 3600 * 1000 * 24 * 90; // expires in 90 days (milliseconds)
		futdate.setTime( expdate );
		var newCookie = 'PageWatcher=' + PageWatcher._formatLinks( links );
		newCookie += '; path=/; domain=de.wikiversity.org;';
		newCookie += ' expires=' + futdate.toGMTString();
		window.document.cookie=newCookie; // Write the cookie
	},

	_usermsg: function( files ) {
		PageWatcher._msgUpdated = PageWatcher._getText(
			PageWatcher._msgUpdated,
			'MediaWiki:PageWatcher-Updates',
			'There are updates for files you are watching'
		);
		var msg = document.createElement( 'a' );
		var reducedWatchfile = PageWatcher._watchfile;
		if( reducedWatchfile.indexOf( '.' ) > 0 ) { // Ziellink als Lemma ohne Punkt-Anhang
			reducedWatchfile = reducedWatchfile.substr( 0, reducedWatchfile.indexOf( '.' ) );
		}
		msg.setAttribute( 'href', mw.config.get('wgServer') + '/wiki/User:' + mw.config.get('wgUserName') + reducedWatchfile );
		msg.setAttribute( 'title', 'User:' + mw.config.get('wgUserName') + reducedWatchfile );
		msg.appendChild( document.createTextNode( PageWatcher._msgUpdated ) );
		var msgDiv = document.createElement( 'div' );
		msgDiv.setAttribute( 'class', 'usermessage mw-topbox' );
		msgDiv.appendChild( msg );
		for ( key in files ) {
			var aFile = document.createElement( 'a' );
			aFile.setAttribute( 'href', mw.config.get('wgServer') + '/wiki/' + key );
			aFile.setAttribute( 'title', key.replace( /_/g, ' ' ) );
			aFile.appendChild( document.createTextNode( key.replace( /_/g, ' ' ) ) );
			msgDiv.appendChild( document.createTextNode( ' ' ) );
			msgDiv.appendChild( aFile );
			msgDiv.appendChild( document.createTextNode( ';' ) );
		}
		var msgContainer = document.getElementById( 'bodyContent' );
		if ( !msgContainer && getElementsByClassName( document, 'div', 'mw-topboxes' ) ) {
			msgContainer = getElementsByClassName( document, 'div', 'mw-topboxes' )[0];
		}
		msgContainer.insertBefore( msgDiv, msgContainer.firstChild );
	},

	watch: function() {
		if(
			typeof mw.config.get('wgAction') != 'undefined' && mw.config.get('wgAction') == 'edit' ||	// im Editmodus keine Überwachung
			mw.config.get('wgCanonicalNamespace') == 'Special' // auf Spezialseiten keine Überwachung
		)
		{
			return false;
		}
		PageWatcher._myDate = new Date();
		PageWatcher._watchfile = '/' + PageWatcher._getText(
			PageWatcher._watchfile,
			'MediaWiki:PageWatcher-File',
			'WatchFile.js'
		);
		PageWatcher._watchfile = PageWatcher._watchfile.replace( /\s/g, '' );
		if ( mw.config.get('wgPageName').indexOf( PageWatcher._watchfile ) > 1 ) {
			return false; // auf der Aboliste keine Überwachung
		}
		request = PageWatcher._get( 'User:' + mw.config.get('wgUserName') + PageWatcher._watchfile, 'raw' );
		if( !request || request.status >= 400 ) {
			return false; // keine Aboliste -> keine Überwachung
		}
		var links = PageWatcher._extractLinks( request.responseText );
		var cookies = {};
		if ( PageWatcher._hasCookies() ) {
			var content = decodeURIComponent( document.cookie.substring( document.cookie.indexOf( '=' ) + 1 ) );
			cookies = PageWatcher._extractLinks( content );
		}
		var unbold = false;
		var updated = false;
		var updatedFiles = {};
		for ( key in links ) {
			if ( cookies[key] ) {
				links[key] = cookies[key];
			}
			if ( !links[key] ) {
				links[key] = '00.00, 0000';
			}
			if ( links[key].indexOf( "'" ) >= 0 ) {
				unbold = true;
			}
			links[key] = links[key].replace( /'/g, '' );
			var lastversion = PageWatcher._lastModified( key );
			if(lastversion && links[key] != lastversion ) {
				links[key] = "'''" + lastversion + "'''";
				updated = true;
				updatedFiles[key] = 1;
			}
		}
		PageWatcher._setCookies( links );
		if ( ( unbold || updated ) && ( PageWatcher._hasCookies() || PageWatcher._editAboList( links ) ) ) {
			if( updated ) {
				PageWatcher._usermsg( updatedFiles );
			}
		}
	}
};

$( PageWatcher.watch );