<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>http://thirdworldcup.ru/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-markblocked.js</id>
	<title>MediaWiki:Gadget-markblocked.js - История изменений</title>
	<link rel="self" type="application/atom+xml" href="http://thirdworldcup.ru/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadget-markblocked.js"/>
	<link rel="alternate" type="text/html" href="http://thirdworldcup.ru/index.php?title=MediaWiki:Gadget-markblocked.js&amp;action=history"/>
	<updated>2026-06-07T14:38:40Z</updated>
	<subtitle>История изменений этой страницы в вики</subtitle>
	<generator>MediaWiki 1.45.3</generator>
	<entry>
		<id>http://thirdworldcup.ru/index.php?title=MediaWiki:Gadget-markblocked.js&amp;diff=41891&amp;oldid=prev</id>
		<title>Шаблонист: Новая страница: «$( function () { 	var _config = { 			mbNoAutoStart: false, 			mbTooltip: &#039;;$1 blocked ($2) by $3: $4 ($5 ago)&#039;, 			mbTempStyle: &#039;opacity:0.7; text-decoration:line...»</title>
		<link rel="alternate" type="text/html" href="http://thirdworldcup.ru/index.php?title=MediaWiki:Gadget-markblocked.js&amp;diff=41891&amp;oldid=prev"/>
		<updated>2021-12-31T07:46:36Z</updated>

		<summary type="html">&lt;p&gt;Новая страница: «$( function () { 	var _config = { 			mbNoAutoStart: false, 			mbTooltip: &amp;#039;;$1 blocked ($2) by $3: $4 ($5 ago)&amp;#039;, 			mbTempStyle: &amp;#039;opacity:0.7; text-decoration:line...»&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;$( function () {&lt;br /&gt;
	var _config = {&lt;br /&gt;
			mbNoAutoStart: false,&lt;br /&gt;
			mbTooltip: &amp;#039;;$1 blocked ($2) by $3: $4 ($5 ago)&amp;#039;,&lt;br /&gt;
			mbTempStyle: &amp;#039;opacity:0.7; text-decoration:line-through;&amp;#039;,&lt;br /&gt;
			mbIndefStyle: &amp;#039;opacity:0.4; font-style:italic; text-decoration:line-through;&amp;#039;,&lt;br /&gt;
			mbTipBox: null,&lt;br /&gt;
			mbTipBoxStyle: &amp;#039;font-size:85%; background:#FFFFF0; border:1px solid #FEA; padding:0 0.3em; color:#AAA;&amp;#039;,&lt;br /&gt;
			mbLoadingOpacity: 0.85&lt;br /&gt;
		},&lt;br /&gt;
		_wasRunned = false,&lt;br /&gt;
		_api,&lt;br /&gt;
		_userNS = [],&lt;br /&gt;
		_userTitleRX,&lt;br /&gt;
		_articleRX,&lt;br /&gt;
		_scriptRX,&lt;br /&gt;
		_$portletLink,&lt;br /&gt;
		_users = {},&lt;br /&gt;
		_processedLinks = [];&lt;br /&gt;
		&lt;br /&gt;
	/******* UTIL *******/&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, &amp;#039;&amp;#039; ).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 ) + &amp;#039;s&amp;#039;;&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 ? &amp;#039;.&amp;#039; + zz( hh ) : &amp;#039;&amp;#039; ) + &amp;#039;d&amp;#039;;&lt;br /&gt;
		}&lt;br /&gt;
		return hh + &amp;#039;:&amp;#039; + zz( mm );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function zz( v ) { // 6 -&amp;gt; &amp;#039;06&amp;#039;&lt;br /&gt;
		if ( v &amp;lt;= 9 ) {&lt;br /&gt;
			v = &amp;#039;0&amp;#039; + v;&lt;br /&gt;
		}&lt;br /&gt;
		return v;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	/******* PUBLIC *******/&lt;br /&gt;
&lt;br /&gt;
	function markBlocked( container ) {&lt;br /&gt;
		var contentLinks, userLinks, users, user, promises, waitingCSS;&lt;br /&gt;
			&lt;br /&gt;
		// Find all links in the entire document on first run or in the provided container&lt;br /&gt;
		contentLinks = !_wasRunned || !container&lt;br /&gt;
			? ( mw.util.$content || $( &amp;#039;.mw-body&amp;#039; ) ).find( &amp;#039;a&amp;#039; ).add( &amp;#039;#ca-nstab-user a&amp;#039; )&lt;br /&gt;
			: $( container ).find( &amp;#039;a&amp;#039; );&lt;br /&gt;
&lt;br /&gt;
		// Find all user links and save them: { &amp;#039;users&amp;#039;: [&amp;lt;link1&amp;gt;, &amp;lt;link2&amp;gt;, ...], &amp;#039;user2&amp;#039;: [&amp;lt;link3&amp;gt;, &amp;lt;link3&amp;gt;, ...], ... }&lt;br /&gt;
		userLinks = {};&lt;br /&gt;
		contentLinks.each( function( i, link ) {&lt;br /&gt;
			if ( _processedLinks.indexOf( link ) !== -1 ) {&lt;br /&gt;
				return;&lt;br /&gt;
			}&lt;br /&gt;
			user = getLinkUser( link );&lt;br /&gt;
			if ( user ) {&lt;br /&gt;
				if ( !userLinks[user] ) {&lt;br /&gt;
					userLinks[user] = [];&lt;br /&gt;
				}&lt;br /&gt;
				userLinks[user].push( link );&lt;br /&gt;
				_processedLinks.push( link );&lt;br /&gt;
			}&lt;br /&gt;
		} );&lt;br /&gt;
&lt;br /&gt;
		// Filter users whose data need to be retrieved into an array&lt;br /&gt;
		users = Object.keys( userLinks ).filter( function ( user ) {&lt;br /&gt;
			return !_users[user];&lt;br /&gt;
		});&lt;br /&gt;
		if ( !users || users.length === 0 ) {&lt;br /&gt;
			markLinks( userLinks );&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
	&lt;br /&gt;
		// API requests&lt;br /&gt;
		waitingCSS = mw.util.addCSS( &amp;#039;a.userlink {opacity:&amp;#039; + _config.mbLoadingOpacity + &amp;#039;}&amp;#039; );&lt;br /&gt;
		promises = [];&lt;br /&gt;
		while ( users.length &amp;gt; 0 ) {&lt;br /&gt;
			promises.push(&lt;br /&gt;
				request( users.splice( 0, 50 ) )&lt;br /&gt;
			);&lt;br /&gt;
		}&lt;br /&gt;
		$.when.apply($, promises).always( function () {&lt;br /&gt;
			markLinks( userLinks );&lt;br /&gt;
			waitingCSS.disabled = true;&lt;br /&gt;
			_$portletLink &amp;amp;&amp;amp; _$portletLink.remove();&lt;br /&gt;
		} );&lt;br /&gt;
&lt;br /&gt;
		if ( !_wasRunned ) {&lt;br /&gt;
			_wasRunned = true;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	function getLinkUser( link ) {&lt;br /&gt;
		var ma, pgTitle, user,&lt;br /&gt;
			$link = $( link ),&lt;br /&gt;
			url = $link.attr( &amp;#039;href&amp;#039; );&lt;br /&gt;
		if ( !url || url.charAt( 0 ) !== &amp;#039;/&amp;#039; ) {&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, &amp;#039; &amp;#039; );&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 ( user === &amp;#039;К удалению&amp;#039; ) {&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
		$link.addClass( &amp;#039;userlink&amp;#039; );&lt;br /&gt;
		return user;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	function request( users ) {&lt;br /&gt;
		var params = {&lt;br /&gt;
			action: &amp;#039;query&amp;#039;,&lt;br /&gt;
			list: &amp;#039;blocks&amp;#039;,&lt;br /&gt;
			bklimit: 100,&lt;br /&gt;
			bkusers: users,&lt;br /&gt;
			bkprop: [ &amp;#039;user&amp;#039;, &amp;#039;by&amp;#039;, &amp;#039;timestamp&amp;#039;, &amp;#039;expiry&amp;#039;, &amp;#039;reason&amp;#039;, &amp;#039;flags&amp;#039; ],&lt;br /&gt;
			format: &amp;#039;json&amp;#039;&lt;br /&gt;
		};&lt;br /&gt;
		return _api&lt;br /&gt;
			.post( params )&lt;br /&gt;
			.then( response );&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	function response( data, xhr ) {&lt;br /&gt;
		var list, user,&lt;br /&gt;
			serverTime = new Date( xhr.getResponseHeader(&amp;#039;Date&amp;#039;) );&lt;br /&gt;
		&lt;br /&gt;
		if ( !data || !data.query || !data.query.blocks ) {&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		list =  data.query.blocks;&lt;br /&gt;
		list.forEach( function ( item, i ) {&lt;br /&gt;
			user = {&lt;br /&gt;
				name: item.user,&lt;br /&gt;
				data: item,&lt;br /&gt;
				partial: &amp;#039;&amp;#039;&lt;br /&gt;
			};&lt;br /&gt;
			if ( /^in/.test( user.data.expiry ) ) {&lt;br /&gt;
				user.class = &amp;#039;user-blocked-indef&amp;#039;;&lt;br /&gt;
				user.blTime = user.data.expiry;&lt;br /&gt;
			} else {&lt;br /&gt;
				user.class = &amp;#039;user-blocked-temp&amp;#039;;&lt;br /&gt;
				user.blTime = inHours ( parseTS( user.data.expiry ) - parseTS( user.data.timestamp ) );&lt;br /&gt;
			}&lt;br /&gt;
			if ( &amp;#039;partial&amp;#039; in user.data ) {&lt;br /&gt;
				user.class = &amp;#039;user-blocked-partial&amp;#039;;&lt;br /&gt;
				user.partial = &amp;#039; partial&amp;#039;;&lt;br /&gt;
			} &lt;br /&gt;
			user.message = _config.mbTooltip&lt;br /&gt;
				.replace( &amp;#039;$1&amp;#039;, user.partial )&lt;br /&gt;
				.replace( &amp;#039;$2&amp;#039;, user.blTime )&lt;br /&gt;
				.replace( &amp;#039;$3&amp;#039;, user.data.by )&lt;br /&gt;
				.replace( &amp;#039;$4&amp;#039;, user.data.reason )&lt;br /&gt;
				.replace( &amp;#039;$5&amp;#039;, inHours ( serverTime - parseTS( user.data.timestamp ) ) );&lt;br /&gt;
			// Export user data&lt;br /&gt;
			_users[user.name] = user;&lt;br /&gt;
		} );&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	function markLinks( userLinks ) {&lt;br /&gt;
		var user, $link;&lt;br /&gt;
		$.each( userLinks, function ( userName, links ) {&lt;br /&gt;
			user = _users[userName];&lt;br /&gt;
			if ( !user ) {&lt;br /&gt;
				return;&lt;br /&gt;
			}&lt;br /&gt;
			links.forEach( function ( link ) {&lt;br /&gt;
				$link = $( link ).addClass( user.class );&lt;br /&gt;
				if ( _config.mbTipBox ) {&lt;br /&gt;
					$( &amp;#039;&amp;lt;span class=&amp;quot;user-blocked-tipbox&amp;quot;&amp;gt;#&amp;lt;/span&amp;gt;&amp;#039; )&lt;br /&gt;
						.attr( &amp;#039;title&amp;#039;, user.message )&lt;br /&gt;
						.insertBefore( $link );&lt;br /&gt;
				} else {&lt;br /&gt;
					$link.attr( &amp;#039;title&amp;#039;, $link.attr( &amp;#039;title&amp;#039; ) + user.message );&lt;br /&gt;
				}&lt;br /&gt;
			} );&lt;br /&gt;
		} );&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	function prepare() {&lt;br /&gt;
		var wgNamespaceIds;&lt;br /&gt;
		// Merge user config&lt;br /&gt;
		_config = $.extend( _config, {&lt;br /&gt;
			mbNoAutoStart: window.mbNoAutoStart,&lt;br /&gt;
			mbTooltip: window.mbTooltip,&lt;br /&gt;
			mbTempStyle: window.mbTempStyle,&lt;br /&gt;
			mbIndefStyle: window.mbIndefStyle,&lt;br /&gt;
			mbTipBox: window.mbTipBox,&lt;br /&gt;
			mbTipBoxStyle: window.mbTipBoxStyle,&lt;br /&gt;
			mbLoadingOpacity: window.mbLoadingOpacity&lt;br /&gt;
		} );&lt;br /&gt;
		_api = new mw.Api();&lt;br /&gt;
		// Get all aliases for user: &amp;amp; user_talk:&lt;br /&gt;
		wgNamespaceIds = mw.config.get( &amp;#039;wgNamespaceIds&amp;#039; );&lt;br /&gt;
		$.each( wgNamespaceIds, function( ns, id ) {&lt;br /&gt;
			if ( [ 2, 3 ].indexOf( id ) !== -1 ) {&lt;br /&gt;
				_userNS.push( ns.replace( /_/g, &amp;#039; &amp;#039; ) + &amp;#039;:&amp;#039; );&lt;br /&gt;
			}&lt;br /&gt;
		} );&lt;br /&gt;
		// RegExp  for all titles that are  User: | User_talk: | Special:Contributions/ (localized) | Special:Contributions/ (for userscripts)&lt;br /&gt;
		_userTitleRX = new RegExp( &amp;#039;^&amp;#039;&lt;br /&gt;
			+ &amp;#039;(&amp;#039; + _userNS.join( &amp;#039;|&amp;#039; )&lt;br /&gt;
			+ &amp;#039;|Служебная:Вклад\\/|Special:Contributions\\/&amp;#039;&lt;br /&gt;
			+ &amp;#039;)&amp;#039;&lt;br /&gt;
			+ &amp;#039;([^\\/#]+)$&amp;#039;, &amp;#039;i&amp;#039; );&lt;br /&gt;
		//RegExp for links&lt;br /&gt;
		_articleRX = new RegExp(&lt;br /&gt;
			&amp;#039;^(?:&amp;#039; + mw.config.get( &amp;#039;wgServer&amp;#039; ) + &amp;#039;)?&amp;#039; +&lt;br /&gt;
			mw.config.get( &amp;#039;wgArticlePath&amp;#039; ).replace( &amp;#039;$1&amp;#039;, &amp;#039;&amp;#039; ) + &amp;#039;([^#]+)&amp;#039;&lt;br /&gt;
		);&lt;br /&gt;
		_scriptRX = new RegExp(&lt;br /&gt;
			&amp;#039;^(?:&amp;#039; + mw.config.get( &amp;#039;wgServer&amp;#039; ) + &amp;#039;)?&amp;#039; +&lt;br /&gt;
			mw.config.get( &amp;#039;wgScript&amp;#039; ) + &amp;#039;\\?title=([^#&amp;amp;]+)&amp;#039;&lt;br /&gt;
		);&lt;br /&gt;
		// Add custom css&lt;br /&gt;
		mw.util.addCSS( &amp;#039;\&lt;br /&gt;
			.mediawiki .user-blocked-temp {&amp;#039;   + _config.mbTempStyle + &amp;#039;}\&lt;br /&gt;
			.mediawiki .user-blocked-indef {&amp;#039;  + _config.mbIndefStyle + &amp;#039;}\&lt;br /&gt;
			.mediawiki .user-blocked-tipbox {&amp;#039; + _config.mbTipBoxStyle + &amp;#039;}\&lt;br /&gt;
		&amp;#039; );&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Export (some users can use method with custom context)&lt;br /&gt;
	window.markBlocked = markBlocked;&lt;br /&gt;
	&lt;br /&gt;
	// Start on some pages&lt;br /&gt;
	switch ( mw.config.get( &amp;#039;wgAction&amp;#039; ) ) {&lt;br /&gt;
		case &amp;#039;edit&amp;#039;:&lt;br /&gt;
		case &amp;#039;submit&amp;#039;:&lt;br /&gt;
		case &amp;#039;delete&amp;#039;:	&lt;br /&gt;
			break;&lt;br /&gt;
		case &amp;#039;view&amp;#039;:&lt;br /&gt;
			if ( [ 0, 10 ].indexOf( mw.config.get( &amp;#039;wgNamespaceNumber&amp;#039; ) ) !== -1 ) {&lt;br /&gt;
				break;&lt;br /&gt;
			}&lt;br /&gt;
			// Otherwise continue with default&lt;br /&gt;
		default: // &amp;#039;history&amp;#039;, &amp;#039;purge&amp;#039;&lt;br /&gt;
			// In case if the gadget is loaded directly by URL&lt;br /&gt;
			mw.loader.using( &amp;#039;mediawiki.util&amp;#039; ).done( function () {&lt;br /&gt;
				prepare();&lt;br /&gt;
				if ( _config.mbNoAutoStart ) {&lt;br /&gt;
					_$portletLink = $( mw.util.addPortletLink( &amp;#039;p-cactions&amp;#039;, null, &amp;#039;XX&amp;#039;, &amp;#039;ca-showblocks&amp;#039; ) );&lt;br /&gt;
					_$portletLink.on( &amp;#039;click&amp;#039;, function( e ) {&lt;br /&gt;
						e.preventDefault();&lt;br /&gt;
						markBlocked();&lt;br /&gt;
					} );&lt;br /&gt;
				} else {&lt;br /&gt;
					mw.hook( &amp;#039;wikipage.content&amp;#039; ).add( markBlocked );&lt;br /&gt;
			  		mw.hook( &amp;#039;global.userlinks&amp;#039; ).add( markBlocked );&lt;br /&gt;
				}&lt;br /&gt;
			} );&lt;br /&gt;
	}&lt;br /&gt;
} );&lt;/div&gt;</summary>
		<author><name>Шаблонист</name></author>
	</entry>
</feed>