MediaWiki:Gadget-contribsrange.js
Utseende
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)
- Edge: Hold Ctrl mens du trykker på Oppdater eller trykk Ctrl+F5
/* Special:Contributions Wildcard/CIDR lookup, version [0.2.13]
Originally from: http://en.wikipedia.org/wiki/User:Splarka/contribsrange.js
Notes:
* Uses the API which is faster than most CIDR contrib tools.
* Only currently works if submitted (or called by URL parameter, eg Special:Contributions/User).
** Checks namespace and date options in form.
** Also utilizes &ucstart and &ucend date parameters if supplied manually (not supported in the UI atm).
*** These parameter soverride the form date options.
* Uses: Submit any IP CIDR range /16 or from /24 to /32. Submit any string (at least 3 characters) with a suffixed asterisk.
** eg: [123.123.123.0/24 ] or [123.123.123.* ] or [Willy* ].
* Now keeps searching until it finds crMax (or forever with crshowall=true URI parameter).
** Puts them in a nice collapsed div stack, like enhanced recent changes.
* /25 and /26 ranges now disabled, since they are inaccurate (50 parameter limit), please use /24 (ucuserprefix) or /27 (32 parameters)
*/
(function contribsrange(){
if ( mw.config.get( 'wgCanonicalSpecialPageName' ) !== 'Contributions' ) {
return;
}
var apiQuery = {}; //query object for continuing later
var crLimit = 500; //limit for each query
var crMax = 10000; //bypass with &crshowall=true URI parameter
var crImgHid = '//upload.wikimedia.org/wikipedia/commons/a/ad/Arr_r.png';
var crImgSho = '//upload.wikimedia.org/wikipedia/commons/f/f0/Arr_d.png';
function getMsg( msg ) {
var s = {
'header-text': 'Javascript-enhanced contributions lookup 0.2 enabled. You may enter a CIDR range or append an asterisk to do a prefix search.',
'very-many-results': 'Whoa! Finding a lot. To load everything, click <a href="$1">here</a>. (Warning: May bog down browser!)',
'no-results': 'No changes were found for this wildcard/CIDR range.',
'toogle-all': 'toogle all',
'searching': 'Searching',
'talk': 'talk',
'diff': 'diff',
'n-contributions-found': '$1 contributions found'
}[msg];
if ( s === undefined ) return;
var args = Array.prototype.slice.call(arguments, 1);
$.each( args, function( key, val ) {
s = s.replace( new RegExp( '\\$' + (key + 1) ), val );
});
return s;
}
mw.loader.using( ['jquery.spinner'], function init() {
mw.util.addCSS( '.cr-list {padding-left:5px;}\n.cr-toggle-hidden {padding-left:16px;background: transparent no-repeat center left url("' + crImgHid + '")}'
+ '\n.cr-toggle-shown {padding-left:16px;background: transparent no-repeat center left url("' + crImgSho + '")}\n.mw-mightexist {font-style:italic;}'
+ '\n#results-from-CIDR {border:1px solid black;padding:.5em}\n#prefixcontribs-tog {float:right;border:1px solid black;text-decoration:none;color:black;padding:0 5px;}' );
$( '<div>' )
.text( getMsg( 'header-text' ) )
.appendTo( '#contentSub, #topbar' );
var input = {
target: $( 'input[name="target"]' ).val(),
namespace: $( 'select[name="namespace"]' ).val(),
year: $( 'input[name="year"]' ).val(),
month: $( 'select[name="month"]' ).val()
};
//general optionlets independent of type of search.
apiQuery = {
action: 'query',
format: 'json',
list: 'usercontribs',
ucprop: 'ids|title|timestamp|comment|size|sizediff',
uclimit: parseInt( crLimit, 10 ),
ucdir: 'older'
};
if ( parseInt( input.namespace, 10 ) > -1 ) {
apiQuery.ucnamespace = input.namespace;
}
if ( input.month === '-1' ) { // "all" (should be equivalent to December, shouldn't it?)
input.month = '12';
}
if ( input.year.match( /^[0-9]{4}$/ ) ) { // Looks like a year
// By using 0 as day we get the last date of the previous month
apiQuery.ucstart = ( new Date( parseInt( input.year, 10 ), parseInt( input.month, 10 ), 0 ) ).toISOString();
}
// Override with values from query string if specified
if ( queryString( 'ucstart' ) ) apiQuery.ucstart = queryString( 'ucstart' );
if ( queryString( 'ucend') ) apiQuery.ucend = queryString( 'ucend' );
// CIDR match
var cidrMatches = input.target.match( /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/(2[7-9]|3[0-2]|24|16)/i );
if ( cidrMatches ) {
prefixContribsStartbox();
var cidr = cidrMatches[0];
var range = cidr.match( /[^\/]\d{1,2}$/i )[0];
if ( range === '24' || range === '16') {
//prefixable CIDR, lets do-er
if ( range === '24' ) {
cidr = cidr.match( /\d{1,3}\.\d{1,3}\.\d{1,3}\./ )[0];
} else {
cidr = cidr.match( /\d{1,3}\.\d{1,3}\./ )[0];
}
apiQuery.ucuserprefix = cidr;
} else {
//complex CIDR, lets figure it out
var oct3 = cidr.match( /\.\d{1,3}\//i )[0].replace( /(\.|\/)/g, '' );
cidr = cidr.match( /\d{1,3}\.\d{1,3}\.\d{1,3}\./ )[0];
var num = Math.pow( 2, 32 - range );
var start = oct3 - oct3 % num;
var ucuser = '';
for ( var i = start; i <= start + num; i++ ) {
ucuser += '' + cidr + i;
if ( i !== start + num ) ucuser += '|';
}
apiQuery.ucuser = ucuser;
}
// Simple wildcard match
} else if ( input.target.search( /^.{3,}\*$/i ) === 0 ) {
prefixContribsStartbox();
var prefix = input.target.replace( /\*$/, '' );
prefix = prefix.substr( 0, 1 ).toUpperCase() + prefix.substr( 1 );
apiQuery.ucuserprefix = prefix;
}
$.getJSON( mw.util.wikiScript( 'api' ), apiQuery, prefixContribs );
});
function prefixContribsStartbox() {
var $div = $( '<div id="results-from-CIDR"></div>' ).appendTo( '#mw-content-text' );
$( '<a href="#" id="prefixcontribs-tog">' + getMsg( 'toogle-all' ) + '</a>' ).appendTo( $div )
.on( 'click', function ( e ) {
e.preventDefault();
prefixContribsToggleAll();
});
$div.append( '<span id="prefixcontribs-prog">' + getMsg( 'searching' ) + '</span>' );
$( '#prefixcontribs-prog' ).injectSpinner( 'prefixcontribs-spin' );
}
function prefixContribs( obj ) {
if ( !obj.query || !obj.query.usercontribs ) {
return;
}
var res = $( '#results-from-CIDR' );
if ( !obj.query.usercontribs.length ) {
$.removeSpinner( 'prefixcontribs-spin' );
res.html( getMsg( 'no-results' ) );
return;
}
var $results;
var $li;
$.each( obj.query.usercontribs, function( i, contribution ) {
var id = 'cr-' + escapeID( contribution.user );
var etitle = encodeURIComponent( contribution.title.replace( / /g, '_' ))
.replace( '%2F', '/' )
.replace( '%3A', ':' );
var euser = encodeURIComponent( contribution.user.replace( / /g, '_' ))
.replace( '%2F', '/' )
.replace( '%3A', ':' );
// group each result set based on the user name, create new div for new names
if ( !$( '#' + id ).length ) {
$results = $( '<div id="d-' + id + '"></div>' ).appendTo( res );
$( '<a href="#" id="m-' + id + '" class="cr-toggle-hidden">' + contribution.user + '</a>' )
.appendTo( $results )
.on( 'click', (function( id ) {
return function( e ) {
e.preventDefault();
prefixContribsToggleDiv( id );
};
})( id ));
$results.append( '<ul id="' + id + '" class="cr-list" style="display:none;"></ul>' );
}
$li = $( '<li> ' )
//.append( '<a href="' + mw.util.wikiScript( 'index' ) + '?title=Special:Contributions/' + euser + '">' + contribution.user + '</a>' )
//.append( ' (<a href="' + mw.util.wikiScript( 'index' ) + '?title=User_talk:' + euser + '" class="mw-mightexist">' + getMsg( 'talk' ) + '</a>)' )
.append( ' <a href="' + mw.util.wikiScript( 'index' ) + '?title=' + etitle + '&oldid=' + contribution.revid + '">' + contribution.timestamp.replace( /[TZ]/g, ' ' ) + '</a>' )
.append( ' (<a href="' + mw.util.wikiScript( 'index' ) + '?title=' + etitle + '&diff=prev&oldid=' + contribution.revid + '">' + getMsg( 'diff' ) + '</a>)' )
.append( ' <a href="' + mw.util.wikiScript( 'index' ) + '?title=' + etitle + '">' + contribution.title + '</a>' );
if ( contribution.comment ) {
$li.append( ' (' + contribution.comment + ')' );
}
if ( contribution.sizediff ) {
$li.append( ' [' + contribution.sizediff.toString().replace( /^(\d)/i,'+$1' ) + ']' );
}
$( '#' + id ).append( $li );
});
//continue?
crMax = crMax - obj.query.usercontribs.length;
var prog = $( '#prefixcontribs-prog' );
if ( !obj['query-continue'] || !obj['query-continue'].usercontribs || !obj['query-continue'].usercontribs.uccontinue ) {
$.removeSpinner( 'prefixcontribs-spin' );
prog.remove();
prefixContribsNumerate();
return;
}
apiQuery.uccontinue = obj['query-continue'].usercontribs.uccontinue;
if ( crMax <= 0 && queryString( 'crshowall' ) !== 'true' ) {
var gaurl = document.location.href;
if ( gaurl.indexOf( '#' ) !== -1 ) gaurl = gaurl.substr( 0, gaurl.indexOf( '#' ) );
if ( gaurl.indexOf( '?' ) === -1 ) gaurl += '?';
gaurl += '&crshowall=true';
prog.append( getMsg( 'very-many-results', gaurl ) );
$.removeSpinner( 'prefixcontribs-spin' );
prefixContribsNumerate();
} else {
prog.append( '.' );
$.getJSON( mw.util.wikiScript( 'api' ), apiQuery, prefixContribs );
}
}
function prefixContribsNumerate() {
$( 'ul.cr-list' ).each( function( idx, itm ) {
$( itm ).before( ', ' + getMsg( 'n-contributions-found', $( itm ).find( 'li' ).length));
});
if ( $( 'ul.cr-list' ).length === 1 ) {
prefixContribsToggleDiv( $( 'ul.cr-list' )[0].id );
}
}
function prefixContribsToggleAll() {
$( 'ul.cr-list' ).each( function( key, itm ) {
prefixContribsToggleDiv( $( itm ).prop( 'id' ));
});
}
function prefixContribsToggleDiv( id ) {
var i = $( '#' + id );
var m = $( '#m-' + id );
if ( i.length === 0 || m.length === 0 ) return;
i.toggle();
if ( i.is( ':visible' ) ) {
m.removeClass( 'cr-toggle-hidden' ).addClass( 'cr-toggle-shown' );
} else {
m.removeClass( 'cr-toggle-shown' ).addClass( 'cr-toggle-hidden' );
}
}
function escapeID( txt ) {
var id = txt;
id = id.replace( / /g, '_' );
id = encodeURIComponent( id );
id = id.replace( /\%3A/g, ':') ;
id = id.replace( /\%/g, '.') ;
id = id.replace( /\./g, '_' );
return id;
}
function queryString( p ) {
var re = new RegExp( '[&?#]' + p + '=([^&#]*)' );
var matches = re.exec( document.location );
if ( matches ) {
try {
return decodeURI( matches[1] );
} catch ( e ) {
}
}
return null;
}
//Support for IE8 and older, via: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/toISOString
if ( !Date.prototype.toISOString ) {
(function() {
function pad(number) {
var r = String(number);
if (r.length === 1) {
r = '0' + r;
}
return r;
}
Date.prototype.toISOString = function() {
return this.getUTCFullYear()
+ '-' + pad(this.getUTCMonth() + 1)
+ '-' + pad(this.getUTCDate())
+ 'T' + pad(this.getUTCHours())
+ ':' + pad(this.getUTCMinutes())
+ ':' + pad(this.getUTCSeconds())
+ '.' + String((this.getUTCMilliseconds()/1000).toFixed(3)).slice(2,5)
+ 'Z';
};
}());
}
})();