User:暁月凛奈/MarkRightsGlobal.js

From Meta, a Wikimedia project coordination wiki

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
//<syntaxhighlight lang="javascript">
//MarkRights.js
//[[User:暁月凛奈/MarkRightsGlobal]]
$( function () {
	mw.loader.load( "//meta.wikimedia.org/w/index.php?title=User:暁月凛奈/MarkRightsGlobal.css&action=raw&ctype=text/css", "text/css" );

	var rightsMap = new mw.Map();
	var gRightsMap = new mw.Map();

	window.rightsMap = rightsMap;

	var $users;
	var users;

	var queue1 = [];
	var queue2 = [];
	var i = 0, n = 0;
	var gi = 0;

	var api = new mw.Api();

	var processGlobal = null;

	function getUsername( href ) {
		var url = new URL( href, window.location.href );
		var username = url.searchParams.has( "title" ) ? url.searchParams.get( "title" ) : null;
		if ( username !== null ) {
			return url.searchParams.get( "title" ).replace( "User:", "" ).replace( /_/g, " " );
		}
		/* 如有无法使用的语言版本,将本地化后的User添加至下方 */
		username = url.pathname.match(/\/wiki\/User:(.+?)$/) //en,simple,zh
			|| url.pathname.match(/\/wiki\/Gumagamit:(.+?)$/) //ceb
			|| url.pathname.match(/\/wiki\/Användare:(.+?)$/) //sv
			|| url.pathname.match(/\/wiki\/Benutzer:(.+?)$/) //de male
			|| url.pathname.match(/\/wiki\/Benutzerin:(.+?)$/) //de female
			|| url.pathname.match(/\/wiki\/Utilisateur:(.+?)$/) //fr
			|| url.pathname.match(/\/wiki\/Gebruiker:(.+?)$/) //nl
			|| url.pathname.match(/\/wiki\/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:(.+?)$/) //ru
			|| url.pathname.match(/\/wiki\/Usuario:(.+?)$/) //es male
			|| url.pathname.match(/\/wiki\/Usuaria:(.+?)$/) //es female
			|| url.pathname.match(/\/wiki\/Utente:(.+?)$/) //it
			|| url.pathname.match(/\/wiki\/Wikipedysta:(.+?)$/) //pl
			|| url.pathname.match(/\/wiki\/%D9%85%D8%B3%D8%AA%D8%AE%D8%AF%D9%85:(.+?)$/) //ar,arz
			|| url.pathname.match(/\/wiki\/Gumaramit:(.+?)$/) //war
			|| url.pathname.match(/\/wiki\/Utilizator:(.+?)$/) //ro
			|| url.pathname.match(/\/wiki\/Th%C3%A0nh_vi%C3%AAn:(.+?)$/) //vi
			|| url.pathname.match(/\/wiki\/%E5%88%A9%E7%94%A8%E8%80%85:(.+?)$/) //ja
			|| url.pathname.match(/\/wiki\/Usu%C3%A1rio:(.+?)$/) //pt male
			|| url.pathname.match(/\/wiki\/Usu%C3%A1ria:(.+?)$/) //pt female
			|| url.pathname.match(/\/wiki\/%D0%9A%D0%BE%D1%80%D0%B8%D1%81%D1%82%D1%83%D0%B2%D0%B0%D1%87:(.+?)$/) //uk
			|| url.pathname.match(/\/wiki\/%DA%A9%D8%A7%D8%B1%D8%A8%D8%B1:(.+?)$/) //fa
			|| url.pathname.match(/\/wiki\/%EC%82%AC%EC%9A%A9%EC%9E%90:(.+?)$/) //ko
			|| url.pathname.match(/\/wiki\/%E7%94%A8%E6%88%B6:(.+?)$/); //zh-classical

		if ( username ) {
			return decodeURIComponent( username[ 1 ].replace( /_/g, " " ) );
		}
		return null;
	}

	function done() {
		$users.each( function ( _i, el ) {
			var username = getUsername( $( el ).attr( "href" ) );
			if ( username ) {
				// eslint-disable-next-line no-jquery/no-each-util
				$.each( rightsMap.get( username ) || [], function ( _gi, group ) {
					$( el ).append( "<sup class=\"markrights markrights-" + group + "\"></sup>" );
				} );
			}
		} );
	}
	function gDone() {
		$users.each( function ( _i, el ) {
			var username = getUsername( $( el ).attr( "href" ) );
			if ( username ) {
				// eslint-disable-next-line no-jquery/no-each-util
				$.each( gRightsMap.get( username ) || [], function ( _gi, group ) {
					$( el ).append( "<sup class=\"markrights markrights-global markrights-" + group + "\"></sup>" );
				} );
			}
		} );
	}

	function process( data ) {
		var user;
		if ( data.query && data.query.users ) {
			user = data.query.users;
		} else {
			user = [];
		}
		for ( var j = 0; j < user.length; j++ ) {
			var u = user[ j ];
			if ( u.groups ) {
				u.groups = u.groups.filter( function ( group ) {
					return [ "*", "user", "steward" /* 意外? */ ].indexOf( group ) === -1;
				} );
				rightsMap.set( u.name, u.groups );
			}
		}

		n--;
		if ( n <= 0 ) {
			done();
		}
	}
	function gProcess( data ) {
		var user;

		if ( data.query && data.query.globaluserinfo ) {
			user = data.query.globaluserinfo;
			gRightsMap.set( user.name, user.groups || [] );
		}

		gi--;
		if ( gi <= 0 ) {
			gDone();
		}
	}

	function markUG() {
		// eslint-disable-next-line no-jquery/no-global-selector
		$users = $( "a.mw-userlink:not(.mw-anonuserlink)" );
		users = {};
		$users.each( function ( index, link ) {
			users[ link.textContent ] = true;
		} );

		queue1 = [];
		queue2 = [];
		i = 0;
		n = 0;
		for ( var user in users ) {
			if ( rightsMap.exists( user ) ) {
				delete users[ user ];
				continue;
			}
			queue1.push( user );
			gi++;
			i++;
			if ( i === 50 ) {
				queue2.push( queue1 );
				queue1 = [];
				n++;
				i = 0;
			}
		}
		if ( queue1.length > 0 ) {
			queue2.push( queue1 );
			n++;
		}

		if ( queue2.length ) {
			for ( var j = 0; j < queue2.length; j++ ) {
				api.get( {
					format: "json",
					action: "query",
					list: "users",
					usprop: "groups",
					ususers: queue2[ j ].join( "|" )
				} ).done( process );
			}
		} else {
			done();
		}

		if ( processGlobal === null ) {
			api.get( {
				format: "json",
				action: "query",
				meta: "globaluserinfo"
			} ).done( function ( data ) {

				if ( data.query && data.query.globaluserinfo ) {
					processGlobal = true;
					
					window.globalRightsMap = gRightsMap;

					gi++;
					gProcess( data );

					if ( gi ) {
						for ( var gu in users ) {
							if ( gu === mw.config.get( "wgUserName" ) ) {
								gi--;
								continue;
							} else {
								api.get( {
									format: "json",
									action: "query",
									meta: "globaluserinfo",
									guiuser: gu,
									guiprop: "groups"
								} ).done( gProcess );
							}
						}
					}
				} else {
					processGlobal = false;
				}
			} );
		} else if ( processGlobal ) {
			if ( !gi ) {
				gDone();
				return;
			}
			for ( var gu in users ) {
				if ( gu === mw.config.get( "wgUserName" ) ) {
					gi--;
					continue;
				} else {
					api.get( {
						format: "json",
						action: "query",
						meta: "globaluserinfo",
						guiuser: gu,
						guiprop: "groups"
					} ).done( gProcess );
				}
			}
		}
	};

	if ( mw.config.get( "wgDiffNewId" ) || mw.config.get( "wgDiffOldId" ) ) {
		// 啟用「互動式瀏覽歷史」,切換差異時重新標記
		mw.hook( "wikipage.diff" ).add( function () { // Reload alongside the revision slider
			markUG();
		} );
	} else if ( [ "Recentchanges", "Recentchangeslinked", "Watchlist" ].indexOf( mw.config.get( "wgCanonicalSpecialPageName" ) ) !== -1 ) {
		// 近期/相關變更更新時重新標記
		mw.hook( "wikipage.content" ).add( function ( element ) {
			if ( element.hasClass( "mw-changeslist" ) ) {
				markUG();
			}
		} );
		markUG();
	} else {
		markUG();
	}
} );
//</syntaxhighlight>