<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.endmyopia.org/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-markblocked.js</id>
	<title>MediaWiki:Gadget-markblocked.js - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.endmyopia.org/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-markblocked.js"/>
	<link rel="alternate" type="text/html" href="https://wiki.endmyopia.org/index.php?title=MediaWiki:Gadget-markblocked.js&amp;action=history"/>
	<updated>2026-05-02T11:49:09Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.3</generator>
	<entry>
		<id>https://wiki.endmyopia.org/index.php?title=MediaWiki:Gadget-markblocked.js&amp;diff=4230&amp;oldid=prev</id>
		<title>NottNott: Created page with &quot;/* 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 = 'Sp...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.endmyopia.org/index.php?title=MediaWiki:Gadget-markblocked.js&amp;diff=4230&amp;oldid=prev"/>
		<updated>2020-05-28T19:56:31Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;/* 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 = &amp;#039;Sp...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;/*&lt;br /&gt;
You can import this gadget to other wikis by using mw.loader.load and specifying the local alias for Special:Contributions. For example:&lt;br /&gt;
var markblocked_contributions = 'Special:Contributions';&lt;br /&gt;
mw.loader.load('//en.wikipedia.org/w/index.php?title=MediaWiki:Gadget-markblocked.js&amp;amp;bcache=1&amp;amp;maxage=259200&amp;amp;action=raw&amp;amp;ctype=text/javascript');&lt;br /&gt;
&lt;br /&gt;
This gadget will pull the user accounts and IPs from the history page and will strike out the users that are currently blocked.&lt;br /&gt;
*/&lt;br /&gt;
function markBlocked( container ) {&lt;br /&gt;
	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;&lt;br /&gt;
	var contentLinks;&lt;br /&gt;
&lt;br /&gt;
	// Collect all the links in the page's content&lt;br /&gt;
	if ( container ) {&lt;br /&gt;
		contentLinks = $( container ).find( 'a' );&lt;br /&gt;
	} else if ( mw.util.$content ) {&lt;br /&gt;
		contentLinks = mw.util.$content.find( 'a' ).add( '#ca-nstab-user a' );&lt;br /&gt;
	} else {&lt;br /&gt;
		contentLinks = $();&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	mw.util.addCSS('\&lt;br /&gt;
	a.user-blocked-temp {'   + ( window.mbTempStyle || 'opacity: 0.7; text-decoration: line-through' ) + '}\&lt;br /&gt;
	a.user-blocked-indef {'  + ( window.mbIndefStyle || 'opacity: 0.4; font-style: italic; text-decoration: line-through' ) + '}\&lt;br /&gt;
	a.user-blocked-partial {'  + ( window.mbPartialStyle || 'text-decoration: underline; text-decoration-style: dotted' ) + '}\&lt;br /&gt;
	.user-blocked-tipbox {' + ( window.mbTipBoxStyle || 'font-size:smaller; background:#FFFFF0; border:1px solid #FEA; padding:0 0.3em; color:#AAA' ) + '}\&lt;br /&gt;
	');&lt;br /&gt;
	var mbTooltip =  window.mbTooltip || '; blocked ($1) by $2: $3 ($4 ago)';&lt;br /&gt;
&lt;br /&gt;
	// Get all aliases for user: &amp;amp; user_talk:&lt;br /&gt;
	var userNS = [];&lt;br /&gt;
	for ( var ns in mw.config.get( 'wgNamespaceIds' ) ) {&lt;br /&gt;
		if ( mw.config.get( 'wgNamespaceIds' )[ns] == 2 || mw.config.get( 'wgNamespaceIds' )[ns] == 3 ) {&lt;br /&gt;
			userNS.push( ns.replace( /_/g, ' ' ) + ':' );&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// Let wikis that are importing this gadget specify the local alias of Special:Contributions&lt;br /&gt;
	if ( window.markblocked_contributions === undefined ) {&lt;br /&gt;
		window.markblocked_contributions = 'Special:Contributions';&lt;br /&gt;
	}&lt;br /&gt;
	// RegExp for all titles that are  User:| User_talk: | Special:Contributions/ (for userscripts)&lt;br /&gt;
	var userTitleRX = new RegExp( '^(' + userNS.join( '|' ) + '|' + window.markblocked_contributions + '\\/)+([^\\/#]+)$', 'i' );&lt;br /&gt;
&lt;br /&gt;
	// RegExp for links&lt;br /&gt;
	// articleRX also matches external links in order to support the noping template&lt;br /&gt;
	var articleRX = new RegExp( mw.config.get( 'wgArticlePath' ).replace('$1', '') + '([^#]+)' );&lt;br /&gt;
	var scriptRX =  new RegExp( '^' + mw.config.get( 'wgScript' ) + '\\?title=([^#&amp;amp;]+)' );&lt;br /&gt;
&lt;br /&gt;
	var userLinks = {};&lt;br /&gt;
	var user, url, ma, pgTitle;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	// Find all &amp;quot;user&amp;quot; links and save them in userLinks : { 'users': [&amp;lt;link1&amp;gt;, &amp;lt;link2&amp;gt;, ...], 'user2': [&amp;lt;link3&amp;gt;, &amp;lt;link3&amp;gt;, ...], ... }&lt;br /&gt;
	contentLinks.each( function( i, lnk ) {&lt;br /&gt;
		if( $( lnk ).hasClass(&amp;quot;mw-changeslist-date&amp;quot;) || $( lnk ).parent(&amp;quot;span&amp;quot;).hasClass(&amp;quot;mw-history-undo&amp;quot;) || $(lnk).parent(&amp;quot;span&amp;quot;).hasClass(&amp;quot;mw-rollback-link&amp;quot;) )&lt;br /&gt;
		{&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
		url = $( lnk ).attr( 'href' );&lt;br /&gt;
		if ( !url ) {&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
		if ( ma = articleRX.exec( url ) ) {&lt;br /&gt;
			pgTitle = ma[1];&lt;br /&gt;
		} else if ( ma = scriptRX.exec( url ) ) {&lt;br /&gt;
			pgTitle = ma[1];&lt;br /&gt;
		} else {&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
		pgTitle = decodeURIComponent( pgTitle ).replace( /_/g, ' ' );&lt;br /&gt;
		user = userTitleRX.exec( pgTitle );&lt;br /&gt;
		if ( !user ) {&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
		user = user[2];&lt;br /&gt;
		if( ipv6Regex.test(user) ) user = user.toUpperCase();&lt;br /&gt;
		$( lnk ).addClass( 'userlink' );&lt;br /&gt;
		if ( !userLinks[user] ) {&lt;br /&gt;
			userLinks[user] = [];&lt;br /&gt;
		}&lt;br /&gt;
		userLinks[user].push (lnk );&lt;br /&gt;
	} );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	// Convert users into array&lt;br /&gt;
	var users = [];&lt;br /&gt;
	for ( var u in userLinks ) {&lt;br /&gt;
		users.push( u );&lt;br /&gt;
	}&lt;br /&gt;
	if ( users.length === 0 ) {&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// API request&lt;br /&gt;
	var serverTime, apiRequests = 0;&lt;br /&gt;
	var waitingCSS = mw.util.addCSS( 'a.userlink {opacity:' + ( window.mbLoadingOpacity || 0.85 ) + '}' );&lt;br /&gt;
	while ( users.length &amp;gt; 0 ) {&lt;br /&gt;
		apiRequests++;&lt;br /&gt;
		$.post( &lt;br /&gt;
			mw.util.wikiScript( 'api' ) + '?format=json&amp;amp;action=query',&lt;br /&gt;
			{&lt;br /&gt;
				list: 'blocks',&lt;br /&gt;
				bklimit: 100,&lt;br /&gt;
				bkusers: users.splice( 0, 50 ).join( '|' ),&lt;br /&gt;
				bkprop: 'user|by|timestamp|expiry|reason|restrictions'&lt;br /&gt;
				// no need for 'id|flags'&lt;br /&gt;
			},&lt;br /&gt;
			markLinks&lt;br /&gt;
		);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return; // the end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	// Callback: receive data and mark links&lt;br /&gt;
	function markLinks( resp, status, xhr ) {&lt;br /&gt;
&lt;br /&gt;
		serverTime = new Date( xhr.getResponseHeader('Date') );&lt;br /&gt;
		var list, blk, tip, links, lnk;&lt;br /&gt;
		if ( !resp || !( list = resp.query ) || !( list = list.blocks ) ) {&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		for ( var i = 0; i &amp;lt; list.length; i++ ) {&lt;br /&gt;
			blk = list[i];&lt;br /&gt;
			var partial = blk.restrictions &amp;amp;&amp;amp; !Array.isArray(blk.restrictions); //Partial block&lt;br /&gt;
			if ( /^in/.test( blk.expiry ) ) {&lt;br /&gt;
				clss = partial ? 'user-blocked-partial' : 'user-blocked-indef';&lt;br /&gt;
				blTime = blk.expiry;&lt;br /&gt;
			} else {&lt;br /&gt;
				clss = partial ? 'user-blocked-partial' : 'user-blocked-temp';&lt;br /&gt;
				blTime = inHours ( parseTS( blk.expiry ) - parseTS( blk.timestamp ) );&lt;br /&gt;
			}&lt;br /&gt;
			tip = mbTooltip;&lt;br /&gt;
			if (partial) {&lt;br /&gt;
				tip = tip.replace( 'blocked', 'partially blocked' );&lt;br /&gt;
			}&lt;br /&gt;
			tip = tip.replace( '$1', blTime )&lt;br /&gt;
				.replace( '$2', blk.by )&lt;br /&gt;
				.replace( '$3', blk.reason )&lt;br /&gt;
				.replace( '$4', inHours ( serverTime - parseTS( blk.timestamp ) ) );&lt;br /&gt;
			links = userLinks[blk.user];&lt;br /&gt;
			for ( var k = 0; links &amp;amp;&amp;amp; k &amp;lt; links.length; k++ ) {&lt;br /&gt;
				lnk = $( links[k] );&lt;br /&gt;
				lnk = lnk.addClass( clss );&lt;br /&gt;
				if ( window.mbTipBox ) {&lt;br /&gt;
					$( '&amp;lt;span class=user-blocked-tipbox&amp;gt;#&amp;lt;/span&amp;gt;' ).attr( 'title', tip ).insertBefore( lnk );&lt;br /&gt;
				} else {&lt;br /&gt;
					lnk.attr( 'title', lnk.attr( 'title' ) + tip );&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( --apiRequests === 0 ) { // last response&lt;br /&gt;
			waitingCSS.disabled = true;&lt;br /&gt;
			$( '#ca-showblocks' ).parent().remove(); // remove added portlet link&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	// --------AUX functions&lt;br /&gt;
&lt;br /&gt;
	// 20081226220605  or  2008-01-26T06:34:19Z   -&amp;gt; date&lt;br /&gt;
	function parseTS( ts ) {&lt;br /&gt;
		var m = ts.replace( /\D/g, '' ).match( /(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/ );&lt;br /&gt;
		return new Date ( Date.UTC( m[1], m[2]-1, m[3], m[4], m[5], m[6] ) );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function inHours( ms ) { // milliseconds -&amp;gt; &amp;quot;2:30&amp;quot; or 5,06d or 21d&lt;br /&gt;
		var mm = Math.floor( ms / 60000 );&lt;br /&gt;
		if ( !mm ) {&lt;br /&gt;
			return Math.floor( ms / 1000 ) + 's';&lt;br /&gt;
		}&lt;br /&gt;
		var hh = Math.floor( mm / 60 );&lt;br /&gt;
		mm = mm % 60;&lt;br /&gt;
		var dd = Math.floor( hh / 24 );&lt;br /&gt;
		hh = hh % 24;&lt;br /&gt;
		if ( dd ) {&lt;br /&gt;
			return dd + ( dd &amp;lt; 10 ? '.' + zz( hh ) : '' ) + 'd';&lt;br /&gt;
		}&lt;br /&gt;
		return hh + ':' + zz( mm );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function zz( v ) { // 6 -&amp;gt; '06'&lt;br /&gt;
		if ( v &amp;lt;= 9 ) {&lt;br /&gt;
			v = '0' + v;&lt;br /&gt;
		}&lt;br /&gt;
		return v;&lt;br /&gt;
	}&lt;br /&gt;
}// -- end of main function&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// Start on some pages&lt;br /&gt;
switch ( mw.config.get( 'wgAction' ) ) {&lt;br /&gt;
	case 'edit':&lt;br /&gt;
	case 'submit':&lt;br /&gt;
		break;&lt;br /&gt;
	case 'view':&lt;br /&gt;
		if ( mw.config.get( 'wgNamespaceNumber' ) === 0 ) {&lt;br /&gt;
			break;&lt;br /&gt;
		}&lt;br /&gt;
		// Otherwise continue with default&lt;br /&gt;
	default: // 'history', 'purge'&lt;br /&gt;
		$.when( $.ready, mw.loader.using( 'mediawiki.util' ) ).then( function() {&lt;br /&gt;
			if ( window.mbNoAutoStart ) {&lt;br /&gt;
				var portletLink = mw.util.addPortletLink( 'p-cactions', '', 'XX', 'ca-showblocks' );&lt;br /&gt;
				$( portletLink ).click( function ( e ) {&lt;br /&gt;
					e.preventDefault();&lt;br /&gt;
					markBlocked();&lt;br /&gt;
				} );&lt;br /&gt;
			} else {&lt;br /&gt;
				mw.hook( 'wikipage.content' ).add( markBlocked );&lt;br /&gt;
			}&lt;br /&gt;
  		} );&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>NottNott</name></author>
	</entry>
</feed>