Медијавики:Gadget-markblocked.js — разлика између измена
Пређи на навигацију
Пређи на претрагу
м (1 измена увезена) |
Нема описа измене |
||
| Ред 1: | Ред 1: | ||
/* | |||
You can import this gadget to other wikis by using mw.loader.load and specifying the local alias for Special:Contributions. For example: | |||
var markblocked_contributions = 'Special:Contributions'; | |||
mw.loader.load('//en.wikipedia.org/w/index.php?title=MediaWiki:Gadget-markblocked.js&bcache=1&maxage=259200&action=raw&ctype=text/javascript'); | |||
This gadget will pull the user accounts and IPs from the history page and will strike out the users that are currently blocked. | |||
*/ | |||
function markBlocked( container ) { | function markBlocked( container ) { | ||
var ipv6Regex = /^((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\3)::|:\b|$))|(?!\2\3)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4})$/i; | |||
var contentLinks; | var contentLinks; | ||
| Ред 12: | Ред 20: | ||
mw.util.addCSS('\ | mw.util.addCSS('\ | ||
a.user-blocked-temp {' + ( window.mbTempStyle || 'opacity: 0. | a.user-blocked-temp {' + ( window.mbTempStyle || 'opacity: 0.85; text-decoration: underline' ) + '}\ | ||
a.user-blocked-indef {' + ( window.mbIndefStyle || 'opacity: 0. | a.user-blocked-indef {' + ( window.mbIndefStyle || 'opacity: 0.55; font-style: italic; text-decoration: underline' ) + '}\ | ||
a.user-blocked-partial {' + ( window.mbPartialStyle || 'text-decoration: underline; text-decoration-style: dotted' ) + '}\ | |||
.user-blocked-tipbox {' + ( window.mbTipBoxStyle || 'font-size:smaller; background:#FFFFF0; border:1px solid #FEA; padding:0 0.3em; color:#AAA' ) + '}\ | .user-blocked-tipbox {' + ( window.mbTipBoxStyle || 'font-size:smaller; background:#FFFFF0; border:1px solid #FEA; padding:0 0.3em; color:#AAA' ) + '}\ | ||
'); | '); | ||
var mbTooltip = window.mbTooltip || '; | var mbTooltip = window.mbTooltip || '; блокиран ($1), блокирао $2: $3 (пре $4)'; | ||
// | // Get all aliases for user: & user_talk: | ||
var userNS = []; | var userNS = []; | ||
for ( var ns in mw.config.get( 'wgNamespaceIds' ) ) { | for ( var ns in mw.config.get( 'wgNamespaceIds' ) ) { | ||
| Ред 26: | Ред 35: | ||
} | } | ||
//RegExp for all titles that are User:| User_talk: | Special:Contributions/ (for userscripts) | // Let wikis that are importing this gadget specify the local alias of Special:Contributions | ||
var userTitleRX = new RegExp( '^(' + userNS.join( '|' ) + '| | if ( window.markblocked_contributions === undefined ) { | ||
window.markblocked_contributions = 'Special:Contributions'; | |||
} | |||
// RegExp for all titles that are User:| User_talk: | Special:Contributions/ (for userscripts) | |||
var userTitleRX = new RegExp( '^(' + userNS.join( '|' ) + '|' + window.markblocked_contributions + '\\/)+([^\\/#]+)$', 'i' ); | |||
//RegExp for links | // RegExp for links | ||
var articleRX = new RegExp( | // articleRX also matches external links in order to support the noping template | ||
var articleRX = new RegExp( mw.config.get( 'wgArticlePath' ).replace('$1', '') + '([^#]+)' ); | |||
var scriptRX = new RegExp( '^' + mw.config.get( 'wgScript' ) + '\\?title=([^#&]+)' ); | var scriptRX = new RegExp( '^' + mw.config.get( 'wgScript' ) + '\\?title=([^#&]+)' ); | ||
var userLinks = {}; | var userLinks = {}; | ||
var url, ma, pgTitle; | var user, url, ma, pgTitle; | ||
// | // Find all "user" links and save them in userLinks : { 'users': [<link1>, <link2>, ...], 'user2': [<link3>, <link3>, ...], ... } | ||
contentLinks.each( function( i, lnk ) { | contentLinks.each( function( i, lnk ) { | ||
if( $( lnk ).hasClass("mw-changeslist-date") || $( lnk ).parent("span").hasClass("mw-history-undo") || $(lnk).parent("span").hasClass("mw-rollback-link") ) | |||
{ | |||
return; | |||
} | |||
url = $( lnk ).attr( 'href' ); | url = $( lnk ).attr( 'href' ); | ||
if ( !url | if ( !url ) { | ||
return; | return; | ||
} | } | ||
| Ред 56: | Ред 74: | ||
} | } | ||
user = user[2]; | user = user[2]; | ||
if( ipv6Regex.test(user) ) user = user.toUpperCase(); | |||
$( lnk ).addClass( 'userlink' ); | $( lnk ).addClass( 'userlink' ); | ||
if ( !userLinks[user] ) { | if ( !userLinks[user] ) { | ||
| Ред 64: | Ред 83: | ||
// | // Convert users into array | ||
var users = []; | var users = []; | ||
for ( var u in userLinks ) { | for ( var u in userLinks ) { | ||
users.push( u ); | users.push( u ); | ||
} | } | ||
if ( users.length == 0 ) { | if ( users.length === 0 ) { | ||
return; | return; | ||
} | } | ||
//API request | // API request | ||
var serverTime, apiRequests = 0; | var serverTime, apiRequests = 0; | ||
var waitingCSS = mw.util.addCSS( 'a.userlink {opacity:' + ( window.mbLoadingOpacity || 0.85 ) + '}' ); | var waitingCSS = mw.util.addCSS( 'a.userlink {opacity:' + ( window.mbLoadingOpacity || 0.85 ) + '}' ); | ||
| Ред 84: | Ред 103: | ||
bklimit: 100, | bklimit: 100, | ||
bkusers: users.splice( 0, 50 ).join( '|' ), | bkusers: users.splice( 0, 50 ).join( '|' ), | ||
bkprop: 'user|by|timestamp|expiry|reason' | bkprop: 'user|by|timestamp|expiry|reason|restrictions' | ||
//no need for 'id|flags' | // no need for 'id|flags' | ||
}, | }, | ||
markLinks | markLinks | ||
| Ред 91: | Ред 110: | ||
} | } | ||
return; //the end | return; // the end | ||
// | // Callback: receive data and mark links | ||
function markLinks( resp, status, xhr ) { | function markLinks( resp, status, xhr ) { | ||
| Ред 105: | Ред 124: | ||
for ( var i = 0; i < list.length; i++ ) { | for ( var i = 0; i < list.length; i++ ) { | ||
blk = list[i]; | blk = list[i]; | ||
var partial = blk.restrictions && !Array.isArray(blk.restrictions); //Partial block | |||
if ( /^in/.test( blk.expiry ) ) { | if ( /^in/.test( blk.expiry ) ) { | ||
clss = 'user-blocked-indef'; | clss = partial ? 'user-blocked-partial' : 'user-blocked-indef'; | ||
blTime = blk.expiry; | blTime = blk.expiry; | ||
} else { | } else { | ||
clss = 'user-blocked-temp'; | clss = partial ? 'user-blocked-partial' : 'user-blocked-temp'; | ||
blTime = inHours ( parseTS( blk.expiry ) - parseTS( blk.timestamp ) ); | blTime = inHours ( parseTS( blk.expiry ) - parseTS( blk.timestamp ) ); | ||
} | } | ||
tip = mbTooltip.replace( '$1', blTime ) | tip = mbTooltip; | ||
if (partial) { | |||
tip = tip.replace( 'blocked', 'partially blocked' ); | |||
} | |||
tip = tip.replace( '$1', blTime ) | |||
.replace( '$2', blk.by ) | .replace( '$2', blk.by ) | ||
.replace( '$3', blk.reason ) | .replace( '$3', blk.reason ) | ||
.replace( '$4', inHours ( serverTime - parseTS( blk.timestamp ) ) ); | .replace( '$4', inHours ( serverTime - parseTS( blk.timestamp ) ) ); | ||
links = userLinks[blk.user]; | links = userLinks[blk.user]; | ||
for ( var k = 0; k < links.length; k++ ) { | for ( var k = 0; links && k < links.length; k++ ) { | ||
lnk = $( links[k] ).addClass( clss ); | lnk = $( links[k] ); | ||
lnk = lnk.addClass( clss ); | |||
if ( window.mbTipBox ) { | if ( window.mbTipBox ) { | ||
$( '<span class=user-blocked-tipbox>#</span>' ).attr( 'title', tip ).insertBefore( lnk ); | $( '<span class=user-blocked-tipbox>#</span>' ).attr( 'title', tip ).insertBefore( lnk ); | ||
| Ред 127: | Ред 152: | ||
} | } | ||
if ( --apiRequests == 0 ) { //last response | if ( --apiRequests === 0 ) { // last response | ||
waitingCSS.disabled = true; | waitingCSS.disabled = true; | ||
$( '#ca-showblocks' ).parent().remove(); // remove added portlet link | $( '#ca-showblocks' ).parent().remove(); // remove added portlet link | ||
| Ред 135: | Ред 160: | ||
//--------AUX functions | // --------AUX functions | ||
//20081226220605 or 2008-01-26T06:34:19Z -> date | // 20081226220605 or 2008-01-26T06:34:19Z -> date | ||
function parseTS( ts ) { | function parseTS( ts ) { | ||
var m = ts.replace( /\D/g, '' ).match( /(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/ ); | var m = ts.replace( /\D/g, '' ).match( /(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/ ); | ||
| Ред 143: | Ред 168: | ||
} | } | ||
function inHours( ms ) { //milliseconds -> "2:30" or 5,06d or 21d | function inHours( ms ) { // milliseconds -> "2:30" or 5,06d or 21d | ||
var mm = Math.floor( ms / 60000 ); | var mm = Math.floor( ms / 60000 ); | ||
if ( !mm ) { | if ( !mm ) { | ||
| Ред 167: | Ред 192: | ||
// | // Start on some pages | ||
var container; // Used to limit mainspace activity to just the diff definitions | |||
switch ( mw.config.get( 'wgAction' ) ) { | switch ( mw.config.get( 'wgAction' ) ) { | ||
case 'edit': | case 'edit': | ||
| Ред 173: | Ред 199: | ||
break; | break; | ||
case 'view': | case 'view': | ||
if ( mw.config.get( 'wgNamespaceNumber' ) == 0 ) { | if ( mw.config.get( 'wgNamespaceNumber' ) === 0 ) { | ||
container = $('.diff-title'); | |||
} | } | ||
// | // Otherwise continue with default | ||
default: // 'history', 'purge' | default: // 'history', 'purge' | ||
$.when( $.ready, mw.loader.using( 'mediawiki.util' ) ).then( function() { | $.when( $.ready, mw.loader.using( 'mediawiki.util' ) ).then( function() { | ||
if ( window.mbNoAutoStart ) { | |||
var portletLink = mw.util.addPortletLink( 'p-cactions', '', 'XX', 'ca-showblocks' ); | |||
$( portletLink ).click( function ( e ) { | |||
e.preventDefault(); | |||
markBlocked(); | markBlocked(container); | ||
} | } ); | ||
} else { | |||
mw.hook( 'wikipage.content' ).add( markBlocked(container) ); | |||
} | } | ||
} ); | } ); | ||
} | } | ||
Тренутна верзија на датум 13. март 2021. у 19:36
/*
You can import this gadget to other wikis by using mw.loader.load and specifying the local alias for Special:Contributions. For example:
var markblocked_contributions = 'Special:Contributions';
mw.loader.load('//en.wikipedia.org/w/index.php?title=MediaWiki:Gadget-markblocked.js&bcache=1&maxage=259200&action=raw&ctype=text/javascript');
This gadget will pull the user accounts and IPs from the history page and will strike out the users that are currently blocked.
*/
function markBlocked( container ) {
var ipv6Regex = /^((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\3)::|:\b|$))|(?!\2\3)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4})$/i;
var contentLinks;
// Collect all the links in the page's content
if ( container ) {
contentLinks = $( container ).find( 'a' );
} else if ( mw.util.$content ) {
contentLinks = mw.util.$content.find( 'a' ).add( '#ca-nstab-user a' );
} else {
contentLinks = $();
}
mw.util.addCSS('\
a.user-blocked-temp {' + ( window.mbTempStyle || 'opacity: 0.85; text-decoration: underline' ) + '}\
a.user-blocked-indef {' + ( window.mbIndefStyle || 'opacity: 0.55; font-style: italic; text-decoration: underline' ) + '}\
a.user-blocked-partial {' + ( window.mbPartialStyle || 'text-decoration: underline; text-decoration-style: dotted' ) + '}\
.user-blocked-tipbox {' + ( window.mbTipBoxStyle || 'font-size:smaller; background:#FFFFF0; border:1px solid #FEA; padding:0 0.3em; color:#AAA' ) + '}\
');
var mbTooltip = window.mbTooltip || '; блокиран ($1), блокирао $2: $3 (пре $4)';
// Get all aliases for user: & user_talk:
var userNS = [];
for ( var ns in mw.config.get( 'wgNamespaceIds' ) ) {
if ( mw.config.get( 'wgNamespaceIds' )[ns] == 2 || mw.config.get( 'wgNamespaceIds' )[ns] == 3 ) {
userNS.push( ns.replace( /_/g, ' ' ) + ':' );
}
}
// Let wikis that are importing this gadget specify the local alias of Special:Contributions
if ( window.markblocked_contributions === undefined ) {
window.markblocked_contributions = 'Special:Contributions';
}
// RegExp for all titles that are User:| User_talk: | Special:Contributions/ (for userscripts)
var userTitleRX = new RegExp( '^(' + userNS.join( '|' ) + '|' + window.markblocked_contributions + '\\/)+([^\\/#]+)$', 'i' );
// RegExp for links
// articleRX also matches external links in order to support the noping template
var articleRX = new RegExp( mw.config.get( 'wgArticlePath' ).replace('$1', '') + '([^#]+)' );
var scriptRX = new RegExp( '^' + mw.config.get( 'wgScript' ) + '\\?title=([^#&]+)' );
var userLinks = {};
var user, url, ma, pgTitle;
// Find all "user" links and save them in userLinks : { 'users': [<link1>, <link2>, ...], 'user2': [<link3>, <link3>, ...], ... }
contentLinks.each( function( i, lnk ) {
if( $( lnk ).hasClass("mw-changeslist-date") || $( lnk ).parent("span").hasClass("mw-history-undo") || $(lnk).parent("span").hasClass("mw-rollback-link") )
{
return;
}
url = $( lnk ).attr( 'href' );
if ( !url ) {
return;
}
if ( ma = articleRX.exec( url ) ) {
pgTitle = ma[1];
} else if ( ma = scriptRX.exec( url ) ) {
pgTitle = ma[1];
} else {
return;
}
pgTitle = decodeURIComponent( pgTitle ).replace( /_/g, ' ' );
user = userTitleRX.exec( pgTitle );
if ( !user ) {
return;
}
user = user[2];
if( ipv6Regex.test(user) ) user = user.toUpperCase();
$( lnk ).addClass( 'userlink' );
if ( !userLinks[user] ) {
userLinks[user] = [];
}
userLinks[user].push (lnk );
} );
// Convert users into array
var users = [];
for ( var u in userLinks ) {
users.push( u );
}
if ( users.length === 0 ) {
return;
}
// API request
var serverTime, apiRequests = 0;
var waitingCSS = mw.util.addCSS( 'a.userlink {opacity:' + ( window.mbLoadingOpacity || 0.85 ) + '}' );
while ( users.length > 0 ) {
apiRequests++;
$.post(
mw.util.wikiScript( 'api' ) + '?format=json&action=query',
{
list: 'blocks',
bklimit: 100,
bkusers: users.splice( 0, 50 ).join( '|' ),
bkprop: 'user|by|timestamp|expiry|reason|restrictions'
// no need for 'id|flags'
},
markLinks
);
}
return; // the end
// Callback: receive data and mark links
function markLinks( resp, status, xhr ) {
serverTime = new Date( xhr.getResponseHeader('Date') );
var list, blk, tip, links, lnk;
if ( !resp || !( list = resp.query ) || !( list = list.blocks ) ) {
return;
}
for ( var i = 0; i < list.length; i++ ) {
blk = list[i];
var partial = blk.restrictions && !Array.isArray(blk.restrictions); //Partial block
if ( /^in/.test( blk.expiry ) ) {
clss = partial ? 'user-blocked-partial' : 'user-blocked-indef';
blTime = blk.expiry;
} else {
clss = partial ? 'user-blocked-partial' : 'user-blocked-temp';
blTime = inHours ( parseTS( blk.expiry ) - parseTS( blk.timestamp ) );
}
tip = mbTooltip;
if (partial) {
tip = tip.replace( 'blocked', 'partially blocked' );
}
tip = tip.replace( '$1', blTime )
.replace( '$2', blk.by )
.replace( '$3', blk.reason )
.replace( '$4', inHours ( serverTime - parseTS( blk.timestamp ) ) );
links = userLinks[blk.user];
for ( var k = 0; links && k < links.length; k++ ) {
lnk = $( links[k] );
lnk = lnk.addClass( clss );
if ( window.mbTipBox ) {
$( '<span class=user-blocked-tipbox>#</span>' ).attr( 'title', tip ).insertBefore( lnk );
} else {
lnk.attr( 'title', lnk.attr( 'title' ) + tip );
}
}
}
if ( --apiRequests === 0 ) { // last response
waitingCSS.disabled = true;
$( '#ca-showblocks' ).parent().remove(); // remove added portlet link
}
}
// --------AUX functions
// 20081226220605 or 2008-01-26T06:34:19Z -> date
function parseTS( ts ) {
var m = ts.replace( /\D/g, '' ).match( /(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/ );
return new Date ( Date.UTC( m[1], m[2]-1, m[3], m[4], m[5], m[6] ) );
}
function inHours( ms ) { // milliseconds -> "2:30" or 5,06d or 21d
var mm = Math.floor( ms / 60000 );
if ( !mm ) {
return Math.floor( ms / 1000 ) + 's';
}
var hh = Math.floor( mm / 60 );
mm = mm % 60;
var dd = Math.floor( hh / 24 );
hh = hh % 24;
if ( dd ) {
return dd + ( dd < 10 ? '.' + zz( hh ) : '' ) + 'd';
}
return hh + ':' + zz( mm );
}
function zz( v ) { // 6 -> '06'
if ( v <= 9 ) {
v = '0' + v;
}
return v;
}
}// -- end of main function
// Start on some pages
var container; // Used to limit mainspace activity to just the diff definitions
switch ( mw.config.get( 'wgAction' ) ) {
case 'edit':
case 'submit':
break;
case 'view':
if ( mw.config.get( 'wgNamespaceNumber' ) === 0 ) {
container = $('.diff-title');
}
// Otherwise continue with default
default: // 'history', 'purge'
$.when( $.ready, mw.loader.using( 'mediawiki.util' ) ).then( function() {
if ( window.mbNoAutoStart ) {
var portletLink = mw.util.addPortletLink( 'p-cactions', '', 'XX', 'ca-showblocks' );
$( portletLink ).click( function ( e ) {
e.preventDefault();
markBlocked(container);
} );
} else {
mw.hook( 'wikipage.content' ).add( markBlocked(container) );
}
} );
}