MediaWiki:Gadget-ajaxrecentchanges.js

    来自真佛百科
    Tbpedia>Jon (WMF)2020年8月4日 (二) 05:45的版本 (maintenance: per talk page)
    (差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)

    注意:在发布之后,您可能需要清除浏览器缓存才能看到所作出的变更的影响。

    • Firefox或Safari:按住Shift的同时单击刷新,或按Ctrl-F5Ctrl-R(Mac为⌘-R
    • Google Chrome:Ctrl-Shift-R(Mac为⌘-Shift-R
    • Internet Explorer或Edge:按住Ctrl的同时单击刷新,或按Ctrl-F5
    • Opera:Ctrl-F5
    /* Ajax recent changes and patrolling framework, version [0.0.6a]
    Originally from: http://en.wikipedia.org/wiki/User:Splarka/ajaxrecentchanges.js
    
    Note:
    * Patrol flags/links will sometimes show up where patrolling is not enabled.
    ** This was a bug in the API that generated patrol tokens too often.
    ** Fixed in r49000
    
    Todo:
    * Checkbox for batch patrolling
    
    Wontdo:
    * Parse comments
    * Add (talk|contribs|block) links, click their name, lazy
    * Localize error messages or focus on the log message 'logaction' (wrong tense, but it works fine).
    */
    
    if ( !window.arc_i18n ) {
    	var arc_i18n = {
    		'title': 'Ajax recent changes',
    		'desc': 'Paginated enhanced ajax recent changes and patrolling.',
    		'mypatrol': 'My patrol log',
    		'startstamp': 'Start timestamp (8601)',
    		'limit': 'Limit',
    		'showapb': 'Show ajax patrol buttons',
    		'filterflag': 'Filter by flag',
    		'minor': 'Minor',
    		'bot': 'Bot',
    		'anon': 'Anon',
    		'redirect': 'Redirect',
    		'patrolled': 'Patrolled',
    		'all': 'All',
    		'filtertype': 'Filter by type',
    		'edit': 'Edits',
    		'newpages': 'New pages',
    		'log': 'Logs',
    		'filterns': 'Filter by namespace',
    		'fetch': 'Fetch',
    		'noresults': 'Nothing found.',
    		'diff': 'diff',
    		'hist': 'hist',
    		'patrolbtn': 'Patrol',
    		'logsuffix': ' log',
    		'patroldone': 'done',
    		'nsmain': 'MAIN'
    	};
    }
    
    $( function() {
    	mw.util.addPortletLink( 'p-tb', '/wiki/Special:BlankPage?blankspecial=ajaxrc', arc_i18n.title, 't-ajax-rc', arc_i18n.desc );
    	if (
    		mw.config.get( 'wgCanonicalSpecialPageName' ) &&
    		mw.config.get( 'wgCanonicalSpecialPageName' ).toLowerCase() == 'blankpage' &&
    		mw.util.getParamValue( 'blankspecial' ) == 'ajaxrc'
    	)
    	{
    		document.title = arc_i18n.title;
    		$( ajaxRcForm );
    	}
    } );
    
    function ajaxRcForm() {
    	mw.util.addPortletLink( 'p-tb', '/wiki/Special:Log/patrol?user=' + encodeURIComponent( mw.config.get( 'wgUserName' ) ), arc_i18n.mypatrol );
    	// subvert this Special: page to our own needs.
    	var bcon = document.getElementById( 'bodyContent' ) || document.getElementById( 'mw_contentholder' );
    	mw.util.$content.children( '.firstHeading' )[0] = arc_i18n.title;
    	for ( var i = 0; i < bcon.childNodes.length; i++ ) {
    		var bcur = bcon.childNodes[i];
    		if ( bcur.id != 'siteSub' && bcur.id != 'contentSub' && bcur.className != 'visualClear' ) {
    			while ( bcur.firstChild ) {
    				bcur.removeChild( bcur.firstChild );
    			}
    			if ( bcur.nodeType == 3 ) {
    				bcur.nodeValue = '';
    			}
    		}
    	}
    
    	mw.util.addCSS(
    		'#arc-form {border:1px solid black;padding:.5em;margin:2em;} #arc-out {border:1px solid black;padding:.5em;margin:.5em;}' +
    		'#arc-fetch {padding:0 1em;margin:0 .5em;} .clear {clear:both;} .arc-box {border:1px solid #bbbbbb;padding:.2em;margin:.5em;}' +
    		'.arc-cbox {display:block;float:left;width:11em;white-space:nowrap;overflow:hidden;font-size:80%;margin:0 .f2em;}' +
    		'.arc-box-label {text-align:center;border-bottom:1px solid #bbbbbb;margin-bottom:.3em} .spacer {border:1px solid transparent;margin-right:.5em;}' +
    		'.arc-patrol {border:2px outset #bbbbbb;background-color:#bbbbbb;color:black;padding:2px;margin:3px;text-decoration:none;}'
    	);
    
    	var form = '<form id="arc-form" action="javascript:void(0)">' +
    		'<label for="arc-start">' + arc_i18n.startstamp + ':</label> <input type="text" name="arc-start" id="arc-start" value="" size="25" maxlength="20"/><span class="spacer"></span>' +
    		'<label for="arc-limit">' + arc_i18n.limit + ':</label> <input type="text" name="arc-limit" id="arc-limit" value="50" size="5" maxlength="3"/><span class="spacer"></span>' +
    		'<input type="checkbox" name="arc-patrol-enable" id="arc-patrol-enable" /><label for="arc-patrol-enable">' + arc_i18n.showapb + '</label><br />' +
    		'<div class="arc-box" id="arc-f-boxen">' + arc_i18n.filterflag + ': <span class="spacer"></span>' +
    		'<label for="arc-f-minor">' + arc_i18n.minor + ':</label> <input type="button" name="arc-f-minor" id="arc-f-minor" value="' + arc_i18n.all + '" onclick="ajaxRcFlagChange(this)" /><span class="spacer"></span>' +
    		'<label for="arc-f-bot">' + arc_i18n.bot + ':</label> <input type="button" name="arc-f-bot" id="arc-f-bot" value="!bot" onclick="ajaxRcFlagChange(this)" /><span class="spacer"></span>' +
    		'<label for="arc-f-anon">' + arc_i18n.anon + ':</label> <input type="button" name="arc-f-anon" id="arc-f-anon" value="' + arc_i18n.all + '" onclick="ajaxRcFlagChange(this)" /><span class="spacer"></span>' +
    		'<label for="arc-f-redirect">' + arc_i18n.redirect + ':</label> <input type="button" name="arc-f-redirect" id="arc-f-redirect" value="' + arc_i18n.all + '" onclick="ajaxRcFlagChange(this)" /><span class="spacer"></span>' +
    		'<label for="arc-f-patrolled">' + arc_i18n.patrolled + ':</label> <input type="button" name="arc-f-patrolled" id="arc-f-patrolled" value="' + arc_i18n.all + '" onclick="ajaxRcFlagChange(this)" />' +
    		'</div>' +
    		'<div class="arc-box" id="arc-t-boxen">' + arc_i18n.filtertype + ': <span class="spacer"></span>' +
    		'<input type="checkbox" name="arc-t-edit" id="arc-t-edit" checked="checked" value="edit" /><label for="arc-t-edit">' + arc_i18n.edit + '</label><span class="spacer"></span>' +
    		'<input type="checkbox" name="arc-t-new" id="arc-t-new" checked="checked" value="new" /><label for="arc-t-new">' + arc_i18n.newpages + '</label><span class="spacer"></span>' +
    		'<input type="checkbox" name="arc-t-log" id="arc-t-log" checked="checked" value="log" /><label for="arc-t-log">' + arc_i18n.log + '</label><span class="spacer"></span>' +
    		'</div>' +
    		'<div class="arc-box" id="arc-ns-boxen"><div class="arc-box-label">' + arc_i18n.filterns + '</div></div>' +
    		'' +
    		'<input type="button" name="fetch" value="' + arc_i18n.fetch + '" id="arc-fetch" onclick="ajaxRcFetch()" /><div class="clear"></div>' +
    		'</form>';
    
    	bcon.innerHTML += form + '<div id="arc-out"></div>';
    	mw.loader.load( mw.config.get( 'wgScriptPath' ) + '/api.php?action=query&meta=siteinfo&siprop=namespaces&format=json&callback=ajaxRcFormNamespacesCB' );
    }
    
    function ajaxRcFetch( timestamp, direction ) {
    	document.getElementById( 'arc-fetch' ).setAttribute( 'disabled', 'disabled' );
    	var nav = document.getElementById( 'arc-fetchnav' );
    	if ( nav ) {
    		nav.style.visibility = 'hidden';
    	}
    	$( '#arc-fetch' ).after( $.createSpinner( 'arc-spin' ) );
    
    	// direction
    	var rcdir = '';
    	if ( direction ) {
    		rcdir = '&rcdir=' + direction + '&requestid=' + direction;
    	}
    
    	// start
    	var rcstart = timestamp || document.getElementById( 'arc-start' ).value;
    	rcstart = rcstart.replace( /[^\d]*/g, '' );
    	if ( rcstart !== '' && /^\d{14}$/.test( rcstart ) ) {
    		rcstart = '&rcstart=' + rcstart;
    	} else {
    		rcstart = '';
    	}
    
    	// limit
    	var rclimit = parseInt( document.getElementById( 'arc-limit' ).value );
    	if ( isNaN( rclimit ) ) {
    		rclimit = 100;
    	}
    	rclimit = '&rclimit=' + rclimit;
    
    	// type
    	var tb = document.getElementById( 'arc-t-boxen' ).getElementsByTagName( 'input' );
    	var rctype = [];
    	for ( var i = 0; i < tb.length; i++ ) {
    		if ( tb[i].checked ) {
    			rctype.push( tb[i].value );
    		}
    	}
    	if ( rctype.length > 0 ) {
    		rctype = '&rctype=' + rctype.join( '|' );
    	} else {
    		rctype = '';
    	}
    
    	// show (flags)
    	var fb = document.getElementById( 'arc-f-boxen' ).getElementsByTagName( 'input' );
    	var rcshow = [];
    	for ( i = 0; i < fb.length; i++ ) {
    		if ( fb[i].value != arc_i18n.all ) {
    			rcshow.push( fb[i].value );
    		}
    	}
    	if ( rcshow.length > 0 ) {
    		rcshow = '&rcshow=' + rcshow.join( '|' );
    	} else {
    		rcshow = '';
    	}
    
    	// namespace
    	var nsb = document.getElementById( 'arc-ns-boxen' ).getElementsByTagName( 'input' );
    	var rcnamespace = [];
    	for ( i = 0; i < nsb.length; i++ ) {
    		if ( nsb[i].checked ) {
    			rcnamespace.push( nsb[i].value );
    		}
    	}
    	if ( rcnamespace.length > 0 ) {
    		rcnamespace = '&rcnamespace=' + rcnamespace.join( '|' );
    	} else {
    		rcnamespace = '';
    	}
    
    	// prop & token
    	var rcprop = '&rcprop=user|comment|flags|timestamp|title|ids|sizes|redirect|patrolled|loginfo';
    	var rctoken = '&rctoken=patrol';
    
    	$.ajax( {
    		url: mw.util.wikiScript( 'api' ) + '?action=query&format=json&rawcontinue=&list=recentchanges' + rcdir + rcstart + rclimit + rctype + rcshow + rcnamespace + rcprop + rctoken
    	} ).done( function( data ) {
    		eval( "ajaxRcFetchHandler(" + data + ",'" + data.replace( /\'/g, "`" ) + "')" );
    	} );
    }
    
    function ajaxRcFetchHandler( obj, txt ) {
    	document.getElementById( 'arc-fetch' ).removeAttribute( 'disabled' );
    	$.removeSpinner( 'arc-spin' );
    	var out = document.getElementById( 'arc-out' );
    	var ajaxpatrol = document.getElementById( 'arc-patrol-enable' ).checked;
    	while ( out.firstChild ) {
    		out.removeChild( out.firstChild );
    	}
    	if ( obj.error ) {
    		out.appendChild( document.createTextNode( 'API error: ' + obj.error.code + ' - ' + obj.error.info + '\n' ) );
    		return;
    	}
    	if ( !obj.query || !obj.query.recentchanges ) {
    		out.appendChild( document.createTextNode( 'Unexpected response: ' + txt + '\n' ) );
    		return;
    	}
    	var rc = obj.query.recentchanges;
    	if ( rc.length === 0 ) {
    		out.appendChild( document.createTextNode( arc_i18n.noresults ) );
    		return;
    	}
    
    	var backwards = false;
    	if ( obj.requestid && obj.requestid == 'newer' ) {
    		backwards = true;
    	}
    
    	var nav = document.createElement( 'div' );
    	nav.setAttribute( 'id', 'arc-fetchnav' );
    	if (
    		obj['query-continue'] &&
    		obj['query-continue'].recentchanges &&
    		obj['query-continue'].recentchanges.rcstart
    	)
    	{
    		var rcstart = obj['query-continue'].recentchanges.rcstart;
    		var rcstartnewer = rcstart;
    		var rcstartolder = rcstart;
    		if ( !backwards ) {
    			rcstartnewer = rc[0].timestamp;
    		} else {
    			rcstartolder = rc[0].timestamp;
    		}
    		addLinkChild( nav, 'javascript:ajaxRcFetch("' + rcstartnewer + '","newer")', 'Newer' );
    		addText( nav, ' | ');
    		addLinkChild( nav, 'javascript:ajaxRcFetch("' + rcstartolder + '","older")', 'Older' );
    	} else if ( backwards ) {
    		addLinkChild( nav, 'javascript:ajaxRcFetch()', 'Older' );
    	}
    	out.appendChild( nav );
    
    	var ul = document.createElement( 'ul' );
    	for ( var i = 0; i < rc.length; i++ ) {
    		var r = rc[i];
    		var li = document.createElement( 'li' );
    		var rcid = '';
    		if ( r.type == 'edit' ) {
    			if ( typeof r.patrolled == 'undefined' && r.rcid && r.patroltoken ) {
    				rcid = '&rcid=' + r.rcid;
    			}
    			addText( li, '(' );
    			addLinkChild( li, mw.config.get( 'wgScript' ) + '?oldid=' + r.old_revid + '&diff=' + r.revid + rcid, arc_i18n.diff );
    			addText( li, ') (' );
    			addLinkChild( li, mw.config.get( 'wgScript' ) + '?curid=' + r.pageid + '&action=history', arc_i18n.hist );
    			addText( li, ') . . ' );
    			if ( typeof r.bot != 'undefined' ) {
    				addText( li, 'b', 'span', 'bot' );
    			}
    			if ( typeof r.minor != 'undefined' ) {
    				addText( li, 'm', 'span', 'minor' );
    			}
    			if ( rcid !== '' && r.patroltoken ) {
    				addText( li, '!', 'span', 'unpatrolled' );
    			}
    			addText( li, ' ' );
    			addLinkChild( li, mw.config.get( 'wgScript' ) + '?curid=' + r.pageid, r.title );
    			var size = '' + ( parseInt( r.newlen ) - parseInt( r.oldlen ) );
    			if ( size.substring( 0, 1 ) != '-' ) {
    				size = '+' + size;
    			}
    			addText( li, '; ' + r.timestamp.replace( /[TZ]/ig, ' ' ) + ' . . (' + size + ') . . ' );
    			addLinkChild( li, mw.config.get( 'wgScript' ) + '?title=Special:Contributions&target=' + encodeURIComponent( r.user ), r.user );
    			if ( r.comment ) {
    				addText( li, ' (' + r.comment + ')', 'i' );
    			}
    			if ( ajaxpatrol === true && rcid !== '' && r.patroltoken ) {
    				addLinkChild( li, 'javascript:ajaxRcDoPatrol("' + r.rcid + '","' + encodeURIComponent( encodeURIComponent( r.patroltoken ) ) + '")', arc_i18n.patrolbtn, 'arc-patrol-' + r.rcid, 'arc-patrol' );
    			}
    		} else if ( r.type == 'new' ) {
    			if ( typeof r.patrolled == 'undefined' && r.rcid ) {
    				rcid = '&rcid=' + r.rcid;
    			}
    			addText( li, '(' + arc_i18n.diff + ') (' );
    			addLinkChild( li, mw.config.get( 'wgScript' ) + '?curid=' + r.pageid + '&action=history', arc_i18n.hist );
    			addText( li, ') . . ' );
    			addText( li, 'N', 'span', 'newpage' );
    			if ( rcid !== '' && r.patroltoken ) {
    				addText( li, '!', 'span', 'unpatrolled' );
    			}
    			addText( li, ' ' );
    			addLinkChild( li, mw.config.get( 'wgScript' ) + '?curid=' + r.pageid + rcid, r.title );
    			addText( li, '; ' + r.timestamp.replace( /[TZ]/ig, ' ' ) + ' . . (+' + r.newlen + ') . . ' );
    			addLinkChild( li, mw.config.get( 'wgScript' ) + '?title=Special:Contributions&target=' + encodeURIComponent( r.user ), r.user );
    			if ( r.comment ) {
    				addText( li, ' (' + r.comment + ')', 'i' );
    			}
    			if ( ajaxpatrol === true && rcid !== '' && r.patroltoken ) {
    				addLinkChild( li, 'javascript:ajaxRcDoPatrol("' + r.rcid + '","' + encodeURIComponent( encodeURIComponent( r.patroltoken ) ) + '")', arc_i18n.patrolbtn, 'arc-patrol-' + r.rcid, 'arc-patrol' );
    			}
    		} else if ( r.type == 'log' ) {
    			addText( li, '(' );
    			addLinkChild( li, mw.config.get( 'wgScript' ) + '?title=Special:Log&type=' + r.logtype, r.logtype + arc_i18n, arc_i18n.logsuffix );
    			addText( li, '); ' + r.timestamp.replace( /[TZ]/ig, ' ' ) + ' . . ' );
    			addLinkChild( li, mw.config.get( 'wgScript' ) + '?title=Special:Contributions&target=' + encodeURIComponent( r.user ), r.user );
    			addText( li,' ' + r.logaction + ' ' );
    			addLinkChild( li, mw.config.get( 'wgScript' ) + '?title=' + encodeURIComponent( r.title ), r.title );
    			if ( r.comment ) {
    				addText( li, ' (' + r.comment + ')', 'i' );
    			}
    		}
    		if ( backwards && ul.firstChild ) {
    			ul.insertBefore( li, ul.firstChild );
    		} else {
    			ul.appendChild( li );
    		}
    	}
    	out.appendChild( ul );
    }
    
    function ajaxRcDoPatrol( rcid, token ) {
    	$.ajax( {
    		method: 'POST',
    		url: mw.util.wikiScript( 'api' ),
    		data: {
    			action: 'patrol',
    			format: 'json',
    			requestid: rcid,
    			token: token
    		}
    	} ).done( function( data ) {
    		eval( 'ajaxRcDidPatrol(' + data + ')' );
    	} );
    }
    
    function ajaxRcDidPatrol( obj ) {
    	if ( !obj.requestid ) {
    		return;
    	}
    	if ( obj.error ) {
    		alert( 'API error in patrolling rcid=' + obj.requestid + ' : ' + obj.error.code + '\n' + obj.error.info );
    		return;
    	}
    	var button = document.getElementById( 'arc-patrol-' + obj.requestid );
    	if ( !button || !obj.patrol ) {
    		return;
    	}
    	button.setAttribute( 'href', 'javascript:alert("(' + arc_i18n.patroldone + ')");' );
    	addText( button, ' (' + arc_i18n.patroldone + ')' );
    }
    
    function ajaxRcFlagChange( obj ) {
    	var type = obj.getAttribute( 'id' ).substring( 6 );
    	var val = obj.value;
    	if ( val == type ) {
    		obj.value = '!' + type;
    	} else if ( val == '!' + type ) {
    		obj.value = arc_i18n.all;
    	} else {
    		obj.value = type;
    	}
    }
    
    function ajaxRcFormNamespacesCB( obj ) {
    	if ( !obj.query || !obj.query.namespaces ) {
    		return;
    	}
    	var ns = obj.query.namespaces;
    	var nsb = document.getElementById( 'arc-ns-boxen' );
    	for ( var i in ns ) {
    		if ( typeof i != 'string' || ns[i].id < 0 ) {
    			continue;
    		}
    		var title = ns[i]['*'];
    		if ( ns[i].id === '' ) {
    			title = arc_i18n.nsmain;
    		}
    		var canon = ns[i].canonical || '';
    		addCheckboxChild( nsb, 'arc-ns-' + ns[i].id, i, false, 'arc-ns-' + ns[i].id, title, 'arc-cbox', ns[i].id + ' => ' + canon );
    		//nsb.appendChild( document.createElement( 'br' ) );
    	}
    	var div = nsb.appendChild( document.createElement( 'div' ) );
    	div.setAttribute( 'class', 'clear' );
    }
    
    function addText( obj, txt, elem, classes ) {
    	if ( elem ) {
    		var e = document.createElement( elem );
    		e.appendChild( document.createTextNode( txt ) );
    		if ( classes ) {
    			e.setAttribute( 'class', classes );
    		}
    		obj.appendChild( e );
    		return e;
    	} else {
    		obj.appendChild( document.createTextNode( txt ) );
    	}
    }
    
    function addLinkChild( obj, href, text, id, classes, title ) {
    	if ( !obj || !href || !text ) {
    		return false;
    	}
    	var a = document.createElement( 'a' );
    	a.setAttribute( 'href', href );
    	a.appendChild( document.createTextNode( text ) );
    	if ( id ) {
    		a.setAttribute( 'id', id );
    	}
    	if ( classes ) {
    		a.setAttribute( 'class', classes );
    	}
    	if ( title ) {
    		a.setAttribute( 'title', title );
    	}
    	obj.appendChild( a );
    	return a;
    }
    
    function addCheckboxChild( obj, name, value, checked, id, label, classes, title ) {
    	if ( !obj || !name ) {
    		return false;
    	}
    	var span = document.createElement( 'span' );
    	var c = document.createElement( 'input' );
    	c.setAttribute( 'name', name );
    	c.setAttribute( 'type', 'checkbox' );
    	if ( value ) {
    		c.setAttribute( 'value', value );
    	}
    	if ( checked ) {
    		c.setAttribute( 'checked', 'checked' );
    	}
    	if ( title ) {
    		c.setAttribute( 'title', title );
    	}
    	span.appendChild( c );
    	if ( id ) {
    		c.setAttribute( 'id', id );
    		if ( label ) {
    			var l = document.createElement( 'label' );
    			l.setAttribute( 'for', id );
    			l.appendChild( document.createTextNode( label ) );
    			if ( title ) {
    				l.setAttribute( 'title', title );
    			}
    			span.appendChild( l );
    		}
    	}
    	if ( classes ) {
    		span.setAttribute( 'class', classes );
    	}
    	obj.appendChild( span );
    	return span;
    }
    window.ajaxRcFormNamespacesCB = ajaxRcFormNamespacesCB;