MediaWiki:Gadget-recentchanges.js
Aus Stupidedia, der sinnfreien Enzyklopädie!
Wichtig: Nach dem Speichern musst Du deinem Browser sagen, dass er die neue Version laden soll: Mozilla/Firefox: Strg-Shift-R, IE: Strg-F5, Safari: Cmd-Shift-R, Konqueror: F5.
/**
* Lilsis – autokratisches RC-Überwachungsprogramm
* Autor: [[Benutzer:Phorgo]]
* Lizenz: GNU FDL
*
* Verwendete Dateien:
* [[Datei:Lilsis Logo.svg]]
* [[Datei:Lilsis Button Toggle.svg]]
* [[Datei:Lilsis Button Close.svg]]
* [[Datei:Lilsis Button Open.svg]]
* [[Datei:Lilsis Button Refresh.svg]]
* [[Datei:Lilsis Button Stop.svg]]
* [[Datei:Lilsis Button Options.svg]]
* [[Datei:Lilsis Status Loading.svg]]
* [[Datei:Lilsis Status Error.svg]]
* [[Datei:Lilsis Status Null.svg]]
* [[Datei:Lilsis Status Stopped.svg]]
*
* <nowiki>
*/
// Hintergrundeigenschaften
gRC.changes = {};
gRC.watchlist = [];
gRC.linkboxMoved = false; // Um Schwierigkeiten mit der Boxenhöhenberechnung aus dem Weg zu gehen
gRC.defaultOptions = { // Standardoptionen
rclimit: 6, // Anzahl der zu ladenden Änderungen
timeFormat: '$H:$I:$S', // Zeitformat für die erste Spalte
interval: 10, // Intervall in Sekunden
placeholderRows: 6, // Anzahl der Platzhalterzeilen
slideSpeed: 'normal', // Klappgeschwindigkeit der Box
diffLimit: 50000, // Maximale Größe der anzuzeigenden Versionsunterschiede, um Browserschwierigkeiten bei Mammutänderungen zu vermeiden
automoveLinkbox: true, // Linkbox hoch- und runterschieben
resizable: true // Größer und kleiner ziehen
};
// Bots können ihresgleichen sehen
if ( global.groups.bot === false ) {
gRC.defaultOptions.rcshow = '!bot';
}
gRC.tempOptions = {}; // Temporäre Optionen
gRC.stopped = false;
gRC.requestTime = 0; // Wird benötigt, damit verspätete, inaktuelle Requests ignoriert werden.
gRC.errorLog = [];
gRC.windowZIndex = 0; // Basis-Höhenlage der Fenster, damit wir sie später ordnen können, ohne dass sich ihr z-index beständig erhöht.
gRC.windowIDs = [];
// Konfigurationseigenschaften
gRC.userOptions = $.parseJSON( mw.user.options.get( 'userjs-recentchanges' ) ) || {}; // Benutzeroptionen
gRC.cookieName = 'gRC_show';
gRC.pageLinks = [];
gRC.userLinks = [];
gRC.modules = {};
// Grafiken
gRC.toggleButton = '/images/thumb/a/a0/Lilsis_Button_Toggle.svg/16px-Lilsis_Button_Toggle.svg.png';
gRC.closeButton = '/images/thumb/f/fd/Lilsis_Button_Close.svg/16px-Lilsis_Button_Close.svg.png';
gRC.openButton = '/images/thumb/e/e3/Lilsis_Button_Open.svg/32px-Lilsis_Button_Open.svg.png';
gRC.refreshButton = '/images/thumb/f/f2/Lilsis_Button_Refresh.svg/16px-Lilsis_Button_Refresh.svg.png';
gRC.stopButton = '/images/thumb/c/c8/Lilsis_Button_Stop.svg/16px-Lilsis_Button_Stop.svg.png';
gRC.optionButton = '/images/thumb/2/2d/Lilsis_Button_Options.svg/16px-Lilsis_Button_Options.svg.png';
gRC.statusLoading = '/images/thumb/9/9a/Lilsis_Status_Loading.svg/16px-Lilsis_Status_Loading.svg.png';
gRC.statusError = '/images/thumb/4/4e/Lilsis_Status_Error.svg/16px-Lilsis_Status_Error.svg.png';
gRC.statusNull = '/images/thumb/a/ab/Lilsis_Status_Null.svg/16px-Lilsis_Status_Null.svg.png';
gRC.statusStopped = '/images/thumb/4/4b/Lilsis_Status_Stopped.svg/16px-Lilsis_Status_Stopped.svg.png';
/**
* Initiierung und Containeraufbau
*/
gRC.init = function() {
gRC.createTempOptions();
$( '<div id="gRC" />' ).appendTo( 'body' );
gRC.buildContainer();
gRC.buildHeader();
gRC.buildBody();
gRC.buildTable();
gRC.buildDummies();
gRC.buildTab();
gRC.getWatchlist();
// Cookie setzen, falls nötig
if ( getCookie( gRC.cookieName ) === null ) {
setCookie( gRC.cookieName, '1' );
}
if ( getCookie( gRC.cookieName ) === '0' ) {
gRC.hide();
}
else {
gRC.show( true );
}
}
// Benutzeroptionen überschreiben Standardoptionen, temporäre Optionen überschreiben Benutzeroptionen. Das ist die Ordnung der Dinge.
gRC.createTempOptions = function() {
gRC.tempOptions = {};
// Standardoptionen in die temporäre Abfrage übernehmen
for ( i in gRC.defaultOptions ) {
gRC.tempOptions[i] = gRC.defaultOptions[i];
}
// Benutzeroptionen übernehmen
// null entfernt die jeweilige Option.
for ( i in gRC.userOptions ) {
gRC.tempOptions[i] = gRC.userOptions[i];
if ( gRC.tempOptions[i] === false || gRC.tempOptions[i] === null ) {
delete gRC.tempOptions[i];
}
}
}
gRC.buildContainer = function() {
var container = $( '<div id="gRC-container" />' );
container.appendTo( '#gRC' );
if ( gRC.tempOptions.resizable ) {
container.resizable( { alsoResize: '#gRC-body > div', handles: 'n', resize: function( event, ui ) {
ui.element.css( 'top', '' );
if ( gRC.tempOptions.automoveLinkbox !== undefined ) {
$( '#gPlb_box' ).animate( { bottom: ui.element.height() }, 0 );
gRC.linkboxMoved = true;
}
} } );
}
}
gRC.buildHeader = function() {
// Titel
var title = $( '<div id="gRC-title" />' );
title.html( '<img src="/images/thumb/a/a1/Lilsis_Logo.svg/16px-Lilsis_Logo.svg.png" alt="Logo" /> <span>Lilsis – autokratisches RC-Überwachungsprogramm<span class="time"></span></span>' );
// Buttons
var buttons = $( '<div id="gRC-buttons" />' );
// Status
var image = $( '<img alt="Alles in Ordnung!" id="gRC-status" title="Alles in Ordnung!" />' );
image.attr( 'src', gRC.statusNull );
buttons.append( image );
// Refresh
var image = $( '<img alt="Aktualisieren" id="gRC-refreshButton" class="gRC-button" title="Aktualisieren" />' );
image.attr( 'src', gRC.refreshButton );
buttons.append( image );
// Refresh
var image = $( '<img alt="Anhalten" id="gRC-stopButton" class="gRC-button" title="Anhalten" />' );
image.attr( 'src', gRC.stopButton );
buttons.append( image );
// Optionen
var image = $( '<img alt="Optionen" id="gRC-optionButton" class="gRC-button" title="Optionen" />' );
image.attr( 'src', gRC.optionButton );
buttons.append( image );
// Schließen
var image = $( '<img alt="Schließen" id="gRC-closeButton" class="gRC-button" title="Schließen" />' );
image.attr( 'src', gRC.closeButton );
buttons.append( image );
// Header
var header = $( '<div id="gRC-header" />' );
header.append( title );
header.append( buttons );
header.append( '<div class="visualClear"></div>' ); // Den brauchen wir wegen der float-Elemente
header.appendTo( '#gRC-container' );
$( '#gRC-refreshButton' ).click( gRC.refresh );
$( '#gRC-stopButton' ).click( function() {
clearTimeout( gRC.timeout );
gRC.stopped = true;
$( '#gRC-status' ).attr( 'src', gRC.statusStopped );
$( '#gRC-status' ).attr( 'alt', 'Box gestoppt' );
$( '#gRC-status' ).attr( 'title', 'Box gestoppt' );
} );
$( '#gRC-optionButton' ).click( function() {
gRC.openWindow();
} );
$( '#gRC-closeButton' ).click( gRC.hide );
}
gRC.buildBody = function() {
var body = $( '<div id="gRC-body" />' );
body.append( '<div />' );
body.appendTo( '#gRC-container' );
}
gRC.buildTable = function() {
var table = $( '<table id="gRC-table" cellspacing="0" />' );
// Überhang verstecken, um eventuelle hässliche Scrollbalken zu vermeiden
$( '#gRC-body' ).css( 'overflow', 'hidden' );
// Platzhalterzeilen, damit die Tabelle nicht so leer aussieht, bevor die Daten geladen wurden
table.append( '<tr class="changeRow row-bg0"><td colspan="7">Lade gerade …</td></tr>' );
for ( var i = 0; i < ( parseInt( gRC.tempOptions.placeholderRows ) - 1 ); i++ ) {
var bgClass = ( i % 2 === 1 ) ? 'row-bg0' : 'row-bg1';
table.append( '<tr class="changeRow ' + bgClass + '"><td colspan="7"> </td></tr>' );
}
table.appendTo( '#gRC-body div' );
}
gRC.buildDummies = function() {
var dummy = $( '<div class="gRC-dummy" />' );
dummy.css( 'height', $( '#gRC-container' ).height() );
dummy.appendTo( '#footer' );
// Für Vector brauchen wir einen zusätzlichen Dummy in der Sidebar
if ( skin === 'vector' ) {
var dummy = $( '<div class="gRC-dummy" />' );
dummy.css( 'height', $( '#gRC-container' ).height() );
dummy.appendTo( '#mw-panel' );
}
}
gRC.buildTab = function() {
var tab = $( '<div id="gRC-tab" />' );
var image = $( '<img alt="Öffnen" />' );
image.attr( 'src', gRC.openButton );
tab.append( image );
tab.attr( 'title', 'Öffnen' );
tab.appendTo( '#gRC' );
$( '#gRC-tab' ).click( gRC.show );
}
gRC.show = function( startup ) {
gRC.stopped = false;
gRC.getData( true );
setCookie( gRC.cookieName, '1' );
if ( gRC.tempOptions.slideSpeed.toString().match( /^[0-9\.]+$/ ) !== null ) {
gRC.tempOptions.slideSpeed = parseFloat( gRC.tempOptions.slideSpeed );
}
var speed = ( startup === true ) ? 0 : gRC.tempOptions.slideSpeed;
// Linkbox nach oben schieben, falls nötig
var containerHeight = $( '#gRC-container' ).height();
if ( startup === true ) {
setHook( 'AfterGadgetExecution', function() {
if ( $( '#gPlb_box' ).css( 'bottom' ) === '0px' && gRC.tempOptions.automoveLinkbox !== undefined ) {
$( '#gPlb_box' ).animate( { bottom: containerHeight }, speed );
gRC.linkboxMoved = true;
}
} );
}
else {
if ( $( '#gPlb_box' ).css( 'bottom' ) === '0px' && gRC.tempOptions.automoveLinkbox !== undefined ) {
$( '#gPlb_box' ).animate( { bottom: containerHeight }, speed );
gRC.linkboxMoved = true;
}
}
if ( skin === 'vector' && $( '#gRC-tab' ).css( 'left' ) === '0px' ) {
$( '#mw-panel .gRC-dummy' ).animate( { height: containerHeight }, speed );
}
else {
$( '.gRC-dummy' ).animate( { height: containerHeight }, speed );
}
$( '#gRC-container, .gRC-dummy' ).slideDown( speed );
$( '#gRC-tab' ).slideUp( speed );
}
gRC.hide = function() {
gRC.stopped = true;
clearTimeout( gRC.timeout );
setCookie( gRC.cookieName, '0' );
// Linkbox wieder nach unten schieben
if ( gRC.tempOptions.slideSpeed.toString().match( /^[0-9\.]+$/ ) !== null ) {
gRC.tempOptions.slideSpeed = parseFloat( gRC.tempOptions.slideSpeed );
}
if ( gRC.linkboxMoved === true && gRC.tempOptions.automoveLinkbox !== undefined ) {
$( '#gPlb_box' ).animate( { bottom: 0 }, gRC.tempOptions.slideSpeed );
}
if ( skin === 'vector' && $( '#gRC-tab' ).css( 'left' ) === '0px' ) {
$( '#mw-panel .gRC-dummy' ).animate( { height: $( '#gRC-tab' ).height() }, gRC.tempOptions.slideSpeed );
$( '#mw-panel .gRC-dummy' ).slideDown( gRC.tempOptions.slideSpeed );
$( '#footer .gRC-dummy' ).slideUp( gRC.tempOptions.slideSpeed );
}
else {
$( '.gRC-dummy' ).animate( { height: $( '#gRC-tab' ).height() }, gRC.tempOptions.slideSpeed );
$( '.gRC-dummy' ).slideDown( gRC.tempOptions.slideSpeed );
}
$( '#gRC-container' ).slideUp( gRC.tempOptions.slideSpeed );
$( '#gRC-tab' ).slideDown( gRC.tempOptions.slideSpeed );
}
/**
* Datenabfrage und Tabellenaufbau
*/
gRC.refresh = function() {
gRC.stopped = false;
gRC.getWatchlist();
gRC.getData( true );
}
gRC.getData = function( refresh ) {
if ( gRC.stopped === true ) {
return;
}
// Timeout löschen, um doppelte Requests zu vermeiden
clearTimeout( gRC.timeout );
gRC.timeout = setTimeout( gRC.getData, parseFloat( gRC.tempOptions.interval ) * 1000 );
// Das Ladesymbol anzeigen
if ( gRC.tempOptions.noBlink === undefined ) { // Aber nur, wenn wir das wollen.
$( '#gRC-status' ).attr( 'src', gRC.statusLoading );
}
$( '#gRC-status' ).attr( 'alt', 'Lade gerade …' );
$( '#gRC-status' ).attr( 'title', 'Lade gerade …' );
var query = {
action: 'query',
list: 'recentchanges',
rcprop: 'user|userid|comment|parsedcomment|flags|timestamp|title|ids|sizes|redirect|loginfo|tags',
rctoken: 'patrol'
};
if ( global.groups.sysop === true || global.groups.f === true ) {
query.rcprop += '|patrolled';
query.rctoken = 'patrol';
}
for ( i in gRC.tempOptions ) {
if ( i.match( /^rc/ ) !== null ) {
query[i] = gRC.tempOptions[i];
}
}
if ( query.rcshow !== undefined ) {
if ( query.rcshow.match( /patrolled/ ) !== null && global.groups.sysop === false && global.groups.f === false ) {
query.rcshow = query.rcshow.replace( /\|?!?patrolled/g, '' );
}
}
var requestTime = time.getTime();
gRC.requestTime = requestTime;
api.request( new api.RequestObject( query, 'get' ), gRC.receiveData, [refresh, requestTime] );
}
gRC.receiveData = function( data, zeug, jqxhr ) {
if ( gRC.stopped === true || zeug[1] < gRC.requestTime ) {
return;
}
// Status bearbeiten
if ( jqxhr.status !== 200 ) {
gRC.errorLog.push( { startTime: zeug[1], endTime: time.getTime(), type: 'HTTP', code: jqxhr.status, text: jqxhr.statusText } );
gRC.modules.errorLog.prototype.refreshLog();
// Statusicon aktualisieren
$( '#gRC-status' ).attr( 'src', gRC.statusError );
$( '#gRC-status' ).attr( 'alt', 'HTTP-Error ' + jqxhr.status.toString() + ': ' + jqxhr.statusText );
$( '#gRC-status' ).attr( 'title', 'HTTP-Error ' + jqxhr.status.toString() + ': ' + jqxhr.statusText );
// Tabelleninhalt durch Fehlermeldung ersetzen
$( '#gRC-table' ).html( '' );
for ( var i = 0; i < parseInt( gRC.tempOptions.placeholderRows ); i++ ) {
var bgClass = ( i % 2 === 0 ) ? 'row-bg0' : 'row-bg1';
$( '#gRC-table' ).append( '<tr class="changeRow ' + bgClass + '"><td colspan="7"> </td></tr>' );
}
$( '#gRC-table tr:first td' ).attr( 'colspan', '7' );
$( '#gRC-table tr:first td' ).html( 'HTTP-Error ' + jqxhr.status.toString() + ': ' + jqxhr.statusText );
gRC.changes = {};
return;
}
// Falls die Daten als String zurückkommen, sollen sie in ein Objekt umgewandelt werden.
if ( typeof data !== 'object' ) {
data = $.parseJSON( data );
}
// API-Fehlermeldungen examinieren
if ( data.error !== undefined ) {
var code = data.error.code;
var info = data.error.info;
gRC.errorLog.push( { startTime: zeug[1], endTime: time.getTime(), type: 'API', code: code, text: info } );
gRC.modules.errorLog.prototype.refreshLog();
// Statusicon aktualisieren
$( '#gRC-status' ).attr( 'src', gRC.statusError );
$( '#gRC-status' ).attr( 'alt', 'API-Error ' + code + ': ' + info );
$( '#gRC-status' ).attr( 'title', 'API-Error ' + code + ': ' + info );
// Tabelleninhalt durch Fehlermeldung ersetzen
$( '#gRC-table' ).html( '' );
for ( var i = 0; i < parseInt( gRC.tempOptions.placeholderRows ); i++ ) {
var bgClass = ( i % 2 === 0 ) ? 'row-bg0' : 'row-bg1';
$( '#gRC-table' ).append( '<tr class="changeRow ' + bgClass + '"><td colspan="7"> </td></tr>' );
}
$( '#gRC-table tr:first td' ).attr( 'colspan', '7' );
$( '#gRC-table tr:first td' ).html( 'API-Error ' + code + ': ' + info );
gRC.changes = {};
return;
}
$( '#gRC-status' ).attr( 'src', gRC.statusNull );
$( '#gRC-status' ).attr( 'alt', 'Alles in Ordnung!' );
$( '#gRC-status' ).attr( 'title', 'Alles in Ordnung!' );
var changes = api.makeArray( data );
$( '#gRC-title span.time' ).html( ' – Stand: ' + time.getText( '$W, $D.$M.$Y, $H:$I:$S', gRC.requestTime ) );
// Wenn sich seit dem letzten Request nichts in den LÄ geändert hat, brauchen wir die Tabelle nicht zu aktualisieren, es sei denn, eine Aktualisierung wird erzwungen.
if ( $.toJSON( changes ) === $.toJSON( gRC.changes ) && zeug[0] !== true ) {
return;
}
gRC.changes = changes;
$( '#gRC-body' ).attr( 'style', null ); // overflow soll wieder auf die Standardeinstellung zurückgesetzt werden, damit die Scrollbalken notfalls zur Verfügung stehen
$( '#gRC-table .changeRow' ).remove(); // Bisherige Zeilen entfernen
$.each( changes, function( i ) {
$( '#gRC-table' ).append( gRC.createRow( this, i ) );
} );
for ( var i = $( '#gRC-table tr' ).length; i < parseInt( gRC.tempOptions.placeholderRows ); i++ ) {
var bgClass = ( i % 2 === 0 ) ? 'row-bg0' : 'row-bg1';
$( '#gRC-table' ).append( '<tr class="changeRow ' + bgClass + '"><td colspan="7"> </td></tr>' );
}
}
gRC.createRow = function( change, i ) {
var row = $( '<tr class="changeRow" />' );
// Abwechselnd heller und dunkler Hintergrund
var bgClass = ( i % 2 === 0 ) ? 'row-bg0' : 'row-bg1';
row.addClass( bgClass );
if ( change.title === undefined ) {
row.html( '<td colspan="7"> </td>' );
return row;
}
// Klasse für den Namensraum
row.addClass( 'row-ns-' + change.ns.toString() );
// Klassen für Flags und Konsorten
if ( change.patrolled === undefined && ( global.groups.sysop === true || global.groups.f === true ) ) {
row.addClass( 'row-unpatrolled' );
}
if ( change['new'] !== undefined ) {
row.addClass( 'row-new' );
}
if ( change.minor !== undefined ) {
row.addClass( 'row-minor' );
}
if ( change.bot !== undefined ) {
row.addClass( 'row-bot' );
}
if ( change.anon !== undefined ) {
row.addClass( 'row-anon' );
}
if ( change.redirect !== undefined ) {
row.addClass( 'row-redirect' );
}
// Klassen für Logbucheinträge
if ( change.type === 'log' ) {
row.addClass( 'row-log' );
row.addClass( 'row-logtype-' + change.logtype );
row.addClass( 'row-logaction-' + change.logaction );
}
// Klasse für beobachtete Seiten
if ( $.inArray( change.title, gRC.watchlist ) !== -1 ) {
row.addClass( 'row-watched' );
}
// ID für rcid
row.attr( 'id', 'rcid-' + change.rcid );
row.append( gRC.createWindowCol( change ) );
row.append( gRC.createTimeCol( change ) );
row.append( gRC.createSizeCol( change ) );
row.append( gRC.createFlagCol( change ) );
row.append( gRC.createTitleCol( change ) );
row.append( gRC.createUserCol( change ) );
row.append( gRC.createCommentCol( change ) );
return row;
}
gRC.createWindowCol = function( change ) {
var text = $( '<a title="Erweitertes Fenster öffnen" />' );
text.attr( 'href', 'javascript:gRC.openWindow( ' + $.toJSON( change ) + ' );' );
var plusminus = ( $( '#gRC-window-' + change.rcid.toString() ).length === 0 ) ? '[+]' : '[–]';
text.html( plusminus );
// Spalte erstellen und Inhalt einfügen
var col = $( '<td class="windowCol" />' );
col.append( text );
return col;
}
gRC.createTimeCol = function( change ) {
var text = $( '<span />' );
text.attr( 'title', time.getText( '$W, $D.$M.$Y, $H:$I:$S', change.timestamp ) );
text.html( time.getText( gRC.tempOptions.timeFormat.replace( / /g, ' ' ), change.timestamp ) );
// Spalte erstellen und Inhalt einfügen
var col = $( '<td class="timeCol" />' );
col.append( text );
return col;
}
gRC.createSizeCol = function( change ) {
var col = $( '<td class="sizeCol" />' );
// Logbucheintrag
if ( change.type === 'log' ) {
var text = gRC.createLogLink( change );
}
// Normale Änderung oder Neuerstellung
else {
var text = $( '<span />' );
var oldlen = change.oldlen;
var newlen = change.newlen;
var diff = newlen - oldlen;
// Seitenlänge gleich geblieben
if ( diff === 0 ) {
text.addClass( 'mw-plusminus-null' );
text.attr( 'title', 'Aktuelle Länge: ' + newlen.toString() + ' Bytes' );
text.html( '0' );
}
// Seitenlänge erhöht
else if ( diff > 0 ) {
text.addClass( 'mw-plusminus-pos' );
text.attr( 'title', 'Aktuelle Länge: ' + newlen.toString() + ' Bytes\nVorherige Länge: ' + oldlen.toString() + ' Bytes' );
text.html( '+' + diff.toString() );
}
// Seitenlänge verringert
else {
text.addClass( 'mw-plusminus-neg' );
text.attr( 'title', 'Aktuelle Länge: ' + newlen.toString() + ' Bytes\nVorherige Länge: ' + oldlen.toString() + ' Bytes' );
text.html( diff.toString() );
}
}
// Spalte erstellen und Inhalt einfügen
col.append( text );
return col;
}
gRC.createFlagCol = function( change ) {
var col = $( '<td class="flagCol" />' );
// Unkontrollierte Änderung
if ( change.patrolled === undefined && ( global.groups.sysop === true || global.groups.f === true ) ) {
col.append( '<span title="Nicht-kontrollierte Änderung" class="unpatrolled">!</span>' );
}
// Seite wurde neu erstellt
if ( change['new'] !== undefined ) {
col.append( '<span title="Neue Seite" class="newpage">N</span>' );
}
// Als Kleinigkeit markiert
if ( change.minor !== undefined ) {
col.append( '<span title="Kleine Änderung" class="minoredit">K</span>' );
}
// Wir sind die Bots, Widerstand ist zwecklos!
if ( change.bot !== undefined ) {
col.append( '<span title="Änderung durch einen Bot" class="botedit">B</span>' );
}
return col;
}
gRC.createTitleCol = function( change ) {
var col = $( '<td class="titleCol" />' );
var link = $( '<a class="mw-title" />' );
var redirect = ( change.redirect !== undefined ) ? '?redirect=no' : ''; // Wenn die Seite ein Redirect ist, soll ?redirect=no an die URL angehängt werden, damit wir nicht weitergeleitet werden.
link.attr( 'href', mw.util.wikiGetlink( change.title ) + redirect );
link.attr( 'title', change.title );
link.html( mw.html.escape( change.title ) );
if ( $.inArray( change.title, gRC.watchlist ) !== -1 ) {
link.addClass( '' );
}
col.append( link );
col.append( ' ' );
var text = $( '<span>(</span>' );
var links = new Array();
// Unterschied
if ( change.revid !== 0 ) {
links.push( { href: mw.util.wikiGetlink( change.title ) + '?diff={revid}&rcid={rcid}', title: 'Unterschied', text: 'U' } );
}
// Versionsgeschichte, wenn's die Seite gibt
// Löschen für Diktatoren ( T = Tonne )
if ( change.pageid !== 0 ) {
links.push( { href: mw.util.wikiGetlink( change.title ) + '?action=history', title: 'Versionsgeschichte', text: 'V' } );
if ( global.groups.sysop === true ) {
links.push( { href: mw.util.wikiGetlink( change.title ) + '?action=delete', title: 'Löschen', text: 'T' } );
}
}
// Andernfalls das Logbuch anzeigen
else {
links.push( { href: mw.util.wikiGetlink( 'Spezial:Logbuch' ) + '?page={title_urlc}', title: 'Logbuch', text: 'L' } );
}
$.merge( links, gRC.pageLinks );
var linkCodes = new Array();
$.each( links, function() {
var href = titleToURL( gRC.replaceHolders( this.href, change ) );
var title = ( this.title !== undefined ) ? gRC.replaceHolders( this.title, change ) : gRC.replaceHolders( this.href, change );
var text = gRC.replaceHolders( this.text, change );
var link = $( '<a />' );
link.attr( 'href', href );
link.attr( 'title', title );
link.html( text );
linkCodes.push( link.selfHTML() );
} );
text.append( linkCodes.join( '|' ) );
text.append( ')' );
col.append( text );
return col;
}
gRC.createUserCol = function( change ) {
var col = $( '<td class="userCol" />' );
var user = change.user;
var link = $( '<a class="mw-userlink" />' );
// Bearbeiter ist 'ne IP
if ( change.anon !== undefined ) {
col.append( '<span class="ip">IP</span> ' );
link.attr( 'href', mw.util.wikiGetlink( 'Spezial:Beiträge/' + user ) );
link.attr( 'title', 'Beiträge von ' + user );
}
// Bearbeiter ist angemeldet
else {
link.attr( 'href', mw.util.wikiGetlink( 'Benutzer:' + user ) );
link.attr( 'title', 'Benutzerseite von ' + user );
}
link.html( mw.html.escape( user ) );
col.append( link );
col.append( ' ' );
var text = $( '<span class="mw-usertoollinks">(</span>' );
var links = new Array();
// Diskussionsseite
links.push( { href: 'Benutzer Diskussion:{user}', title: 'Diskussionsseite von {user}', text: 'D' } );
// Beiträge, wenn angemeldet
if ( change.anon === undefined ) {
links.push( { href: 'Spezial:Beiträge/{user}', title: 'Beiträge von {user}', text: 'B' } );
}
// Sperren
if ( global.groups.sysop === true ) {
links.push( { href: 'Spezial:Sperren/{user}', title: '{user} sperren', text: 'S' } );
}
$.merge( links, gRC.userLinks );
var linkCodes = new Array();
$.each( links, function() {
var href = titleToURL( gRC.replaceHolders( this.href, change ) );
var title = ( this.title !== undefined ) ? gRC.replaceHolders( this.title, change ) : gRC.replaceHolders( this.href, change );
var text = gRC.replaceHolders( this.text, change );
var link = $( '<a />' );
link.attr( 'href', href );
link.attr( 'title', title );
link.html( text );
linkCodes.push( link.selfHTML() );
} );
text.append( linkCodes.join( '|' ) );
text.append( ')' );
col.append( text );
return col;
}
gRC.createCommentCol = function( change ) {
var col = $( '<td class="commentCol" />' );
if ( change.tags.length !== 0 ) {
var text = $( '<span class="mw-tag-markers">[</span>' );
var markers = new Array();
$.each( change.tags, function() {
var tag = this;
var marker = $( '<span class="mw-tag-marker" />' );
var tagClass = 'mw-tag-marker-' + tag;
tagClass = tagClass.replace( /(^[0-9\-])|[\x00-\x20!"#$%&'()*+,.\/:;<=>?@[\]^`{|}~]|\xC2\xA0/g, '_' ); // Blöde Zeichen durch Unterstriche ersetzen
tagClass = tagClass.replace( /_+/g, '_' ); // Doppelte Unterstriche zu einem zusammenstauchen
tagClass = tagClass.replace( /_+$/g, '' ); // Unterstriche am Ende entfernen
marker.addClass( tagClass );
marker.html( mw.html.escape( tag ) );
markers.push( marker.selfHTML() );
} );
text.append( markers.join( ', ' ) );
text.append( ']' );
col.append( text );
col.append( ' ' );
}
var text = $( '<span class="comment" />' );
text.html( change.parsedcomment );
col.append( text );
return col;
}
// Beobachtungsliste abfragen
gRC.getWatchlist = function( cont ) {
var query = {
action: 'query',
list: 'watchlistraw',
wrlimit: 'max'
};
// Fortsetzung der vorigen Abfrage bei Limitüberschreitung
if ( cont !== undefined ) {
query.wrcontinue = cont;
}
// Andernfalls die temporäre Beobachtungsliste leeren
else {
gRC.tempWatchlist = [];
}
api.request( new api.RequestObject( query, 'get' ), gRC.setWatchlist );
}
gRC.setWatchlist = function( data ) {
if ( !data ) {
return;
}
$.each( data.watchlistraw, function() {
gRC.tempWatchlist.push( this.title );
} );
// Falls mehr Seiten auf der Liste stehen, als in einem Request abgefragt werden können, wird gRC.getWatchlist() erneut ausgeführt.
if ( data['query-continue'] !== undefined ) {
gRC.getWatchlist( data['query-continue'].watchlistraw.wrcontinue );
}
// Andernfalls wird die temporäre Liste übernommen und die Tabelle aktualisiert.
else {
gRC.watchlist = gRC.tempWatchlist;
gRC.getData( true );
}
}
// Inhalt, href- und title-Attribute in Links setzen
gRC.setLink = function( id, context, href, title, html ) {
title = ( $.type( title ) === 'string' ) ? title : href;
href = titleToURL( href );
$( 'a:eq(' + id.toString() + ')', context ).attr( 'href', href );
$( 'a:eq(' + id.toString() + ')', context ).attr( 'title', title );
if ( html !== undefined ) {
$( 'a:eq(' + id.toString() + ')', context ).html( html );
}
}
gRC.replaceHolders = function( text, change ) {
text = text.replace( /\{change\}/gi, $.toJSON( change ) ); // Änderungsobjekt im JSON-Format
text = text.replace( /\{revid\}/gi, change.revid.toString() ); // Neue Versions-ID
text = text.replace( /\{oldid\}/gi, change.old_revid.toString() ); // Alte Versions-ID
text = text.replace( /\{rcid\}/gi, change.rcid.toString() ); // Änderungs-ID
text = text.replace( /\{ns\}/gi, change.ns.toString() ); // Namensraum-ID
text = text.replace( /\{title\}/gi, change.title ); // Seitentitel
text = text.replace( /\{user\}/gi, change.user ); // Benutzername
text = text.replace( /\{title_url\}/gi, encodeURI( change.title ) ); // Seitentitel url-kodiert
text = text.replace( /\{user_url\}/gi, encodeURI( change.user ) ); // Benutzername url-kodiert
text = text.replace( /\{title_urlc\}/gi, encodeURIComponent( change.title ) ); // Seitentitel url-component-kodiert
text = text.replace( /\{user_urlc\}/gi, encodeURIComponent( change.user ) ); // Benutzername url-component-kodiert
text = text.replace( /\{token_urlc\}/gi, encodeURIComponent( global.editToken ) ); // Bearbeitungstoken url-component-kodiert
text = text.replace( /\{title_html\}/gi, mw.html.escape( change.title ) ); // Seitentitel html-maskiert
text = text.replace( /\{user_html\}/gi, mw.html.escape( change.user ) ); // Benutzername html-maskiert
text = text.replace( /\{title_js\}/gi, change.title.replace( /\\/g, '\\\\' ).replace( /\'/g, '\\\'' ).replace( /\"/g, '\\"' ) ); // Seitentitel js-maskiert
text = text.replace( /\{user_js\}/gi, change.user.replace( /\\/g, '\\\\' ).replace( /\'/g, '\\\'' ).replace( /\"/g, '\\"' ) ); // Benutzername js-maskiert
text = text.replace( /\{token_js\}/gi, global.editToken.replace( /\\/g, '\\\\' ).replace( /\'/g, '\\\'' ).replace( /\"/g, '\\"' ) ); // Bearbeitungstoken js-maskiert
return text;
}
execute( 'gRC.init' );