User:SunAfterRain/js/markrights.js
Appearance
From Meta, a Wikimedia project coordination wiki
< User:SunAfterRain | js
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)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
/** * markrights.js * 在最近修改、監視列表、記錄歷史記錄等位置以特殊情況顯示有特殊權限的用戶 * * 修改自 https://zh.wikipedia.org/w/index.php?title=MediaWiki:Gadget-MarkRights.js&oldid=59130792 * * 請注意當你引用這個頁面時沒有效果是正常的 * 你還需要參考[[User:SunAfterRain/js/markrights.css]] * 在[[Special:MyPage/common.css]](全域:[[Special:MyPage/global.js]])加入對應的css! * * 註: * 此版本同時會嘗試抓取全域權限並標註 * 但全域權限一個請求只能查一個用戶 * 可能導致載入緩慢 * 此功能可以在載入這個小工具前加上 * <syntaxhighlight lang="js">window.wgMarkRightsDoNotProcessGlobal = true;</syntaxhighlight> * 來強制關閉 */ // <nowiki> $.when( $.ready, mw.loader.using(["mediawiki.api","mediawiki.storage","mediawiki.Title","mediawiki.util"]) ).then(()=>{ constrightsMap=newMap(); constgRightsMap=newMap(); let$users; letusers; letqueue1=[]; letqueue2=[]; letdeferreds=[]; leti=0, n=0, gi=0; constprocessGlobalKey="markrights.processGlobal"; letprocessGlobal=mw.storage.get(processGlobalKey); if(window.wgMarkrightsDoNotProcessGlobal){ processGlobal=false; } constdefaultMaxConcurrentRequests=10; constdefaultRequestWaitMs=200; classConcurrentApiextendsmw.Api{ constructor(maxConcurrentRequests,requestWaitMs){ super(); this.inFlightRequests=0; this.requestQueue=[]; this.maxConcurrentRequests=maxConcurrentRequests??defaultMaxConcurrentRequests; this.requestWaitMs=requestWaitMs??defaultRequestWaitMs; } ajax(...reqParams){ constdeferred=$.Deferred(); this.requestQueue.push(()=>super.ajax(...reqParams).then(deferred.resolve,deferred.reject)); this.processQueue(); returndeferred; } processQueue(){ if(this.requestQueue.length>0&&this.inFlightRequests<this.maxConcurrentRequests){ constrequest=this.requestQueue.shift(); this.inFlightRequests++; request().always(()=>{ this.inFlightRequests--; setTimeout(()=>this.processQueue(),this.requestWaitMs); }); } } } constapi=newConcurrentApi(window.wgMarkRightsMaxConcurrentRequests,window.wgMarkRightsRequestWaitMs); constpathReg=newRegExp("^"+mw.util.escapeRegExp(mw.config.get("wgArticlePath")).replace(/\\\1ドル/g/* \1ドル */,'([^\\/]+)')+"$","i"); functiongetUsernameFromTitle(title){ if(title.indexOf(':')>0&&!title.includes('/')){ try{ constmTitle=newmw.Title(title); if(mTitle.namespace===2){ returnmTitle.getMainText(); } }catch(e){ // ignore } } returnnull; } functiongetUsernameInternal(href){ if(!href){ returnnull; } consturl=newURL(href,window.location.href); constqueryTitle=url.searchParams.has("title")?url.searchParams.get("title"):null; if(queryTitle!==null){ returngetUsernameFromTitle(queryTitle); } constmPathname=pathReg.exec(decodeURIComponent(url.pathname)); if(mPathname){ returngetUsernameFromTitle(mPathname[1]); } returnnull; } constgetUsernameCache=newMap(); functiongetUsername(href){ if(getUsernameCache.has(href)){ returngetUsernameCache.get(href); } constresult=getUsernameInternal(href); getUsernameCache.set(href,result); returnresult; } functionprocess(data){ if(data.query&&data.query.users){ constuser=data.query.users; for(letj=0;j<user.length;j++){ constu=user[j]; if(u.groups){ rightsMap.set(u.name,u.groups); } } } } functiongProcess(data){ if(data.query&&data.query.globaluserinfo){ constuser=data.query.globaluserinfo; gRightsMap.set(user.name,user.groups||[]); } } functionbuildMarkrightElement(groupId,isGlobal=false){ constfinalClass=[ 'markrights' ]; if(isGlobal){ finalClass.push('markrights-global'); } finalClass.push('markrights-'+groupId); return$('<sup>').addClass(finalClass); } functionerrorCallback(error){ console.error(error); } functionmarkUG(){ $(".markrights").remove(); // eslint-disable-next-line no-jquery/no-global-selector $users=$([ "a.mw-userlink:not( .mw-anonuserlink )", "ul.mw-logevent-loglines > li > a.userlink", // ".mw-special-GlobalUsers a.userlink", ".mw-contributions-user-tools > a",// Waring: .mw-contributions-user-tools > a.userlink didn't exist in some wiki ].join(",")); users={}; $users.each(function(_i,link){ if(link.textContent){ users[link.textContent]=true; } }); queue1=[]; queue2=[]; deferreds=[]; i=0; n=0; for(constuserinusers){ if(rightsMap.has(user)){ deleteusers[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(letj=0;j<queue2.length;j++){ deferreds.push(api.get({ format:"json", action:"query", list:"users", usprop:"groups", ususers:queue2[j].join("|") }).then(process,errorCallback)); } } if(processGlobal===null){ deferreds.push(api.get({ format:"json", action:"query", meta:"globaluserinfo" }).then(function(data){ constsDeferreds=[]; if(data.query&&data.query.globaluserinfo){ mw.storage.set(processGlobalKey,"true"); processGlobal=true; gi++; gProcess(data); if(gi){ for(constguinusers){ if(gu===mw.config.get("wgUserName")){ gi--; continue; }else{ sDeferreds.push(api.get({ format:"json", action:"query", meta:"globaluserinfo", guiuser:gu, guiprop:"groups" }).then(gProcess,errorCallback)); } } } }else{ mw.storage.set(processGlobalKey,"false"); processGlobal=false; } returnPromise.all(sDeferreds); },errorCallback)); }elseif(processGlobal===true||processGlobal==="true"){ for(constguinusers){ if(gu===mw.config.get("wgUserName")){ continue; }else{ deferreds.push(api.get({ format:"json", action:"query", meta:"globaluserinfo", guiuser:gu, guiprop:"groups" }).then(gProcess,errorCallback)); } } } Promise.all(deferreds) .then(function(){ $users.each(function(_i,el){ constusername=getUsername($(el).attr("href")); if(username){ constappends=[]; (gRightsMap.get(username)||[]).forEach(function(group){ appends.push(buildMarkrightElement(group,true)); }); // eslint-disable-next-line no-jquery/no-each-util (rightsMap.get(username)||[]).filter(function(group){ if(processGlobal&&group==="steward"){// [[mw:Extension:CentralAuth#Setup]]: migrateStewards.php returnfalse; } return["*","user"].indexOf(group)===-1; }).forEach(function(group){ appends.push(buildMarkrightElement(group)); }); $(el).append(...appends.reverse()); } }); }); } if(mw.config.get("wgDiffNewId")||mw.config.get("wgDiffOldId")){ // 啟用「互動式瀏覽歷史」,切換差異時重新標記 mw.hook("wikipage.diff").add(function(){ markUG(); }); }elseif(["Recentchanges","Recentchangeslinked","Watchlist"].indexOf(mw.config.get("wgCanonicalSpecialPageName"))!==-1){ // 近期/相關變更更新時重新標記 mw.hook("wikipage.content").add(function(element){ if(element.hasClass("mw-changeslist")){ markUG(); } }); markUG(); }elseif(mw.config.get("wgCanonicalSpecialPageName")==="Listgrouprights"){ $(".mw-listgrouprights-table tr").each(function(_i,e){ const$e=$(e); if(!$e.attr("id")){ return; } const$exec=$e.children("td:first").children(":first"); letmethod="after"; if(!$exec.length){ return; }elseif($exec.get(0).tagName.toLowerCase()==="br"){ method="before"; } $exec[method](buildMarkrightElement($e.attr("id"))); }); }elseif(mw.config.get("wgCanonicalSpecialPageName")==="GlobalGroupPermissions"){ constbase=mw.util.getUrl(mw.config.get("wgPageName"))+"/"; functionfindGlobalGroupId($a){ return$a.get().filter(function(a){ if($(a).attr("href")&&$(a).attr("href").startsWith(base)){ returntrue; } returnfalse; }).map(function(a){ return$(a).attr("href").slice(base.length); })[0]; } $(".mw-centralauth-groups-table tr").each(function(_i,e){ const$e=$(e); constid=findGlobalGroupId($e.find("a")); if(!id){ return; } const$exec=$e.children("td:first").children(":first"); letmethod="after"; if(!$exec.length){ return; }elseif($exec.get(0).tagName.toLowerCase()==="br"){ method="before"; } $exec[method](buildMarkrightElement(id,true)); }); }else{ markUG(); } }); // </nowiki>