MediaWiki:Gadget-MarkRights.js
MediaWiki界面页面
更多操作
注意:在发布之后,您可能需要清除浏览器缓存才能看到所作出的更改的影响。
- Firefox或Safari:按住Shift的同时单击刷新,或按Ctrl-F5或Ctrl-R(Mac为⌘-R)
- Google Chrome:按Ctrl-Shift-R(Mac为⌘-Shift-R)
- Edge:按住Ctrl的同时单击刷新,或按Ctrl-F5。
/**
* MediaWiki:Gadget-MarkRights.js
*
* 在页面上以特殊格式显示有特殊权限的用户
*
* [Final Production Version - DEBUG ENABLED]
* This version exclusively targets official user link classes (.mw-userlink, .cs-comment-author)
* and filters out links pointing to user subpages for maximum precision.
* Full logging is re-enabled for troubleshooting.
*/
$(function () {
console.log('[MarkRights Debug] Gadget loaded and DOM is ready.');
var groups = {
// ... (您的用户组配置保持不变) ...
// 全站管理型权限
bureaucrat: {list: [], class: "markrights-bureaucrat"},
checkuser: {list: [], class: "markrights-checkuser"},
suppress: {list: [], class: "markrights-suppress"},
sysop: {list: [], class: "markrights-sysop"},
'interface-admin': {list: [], class: "markrights-interface-admin"},
templateeditor: {list: [], class: "markrights-templateeditor"},
transwiki: {list: [], class: "markrights-transwiki"},
'ipblock-exempt-grantor': {list: [], class: "markrights-ipblock-exempt-grantor"},
'temporary-account-viewer': {list: [], class: "markrights-temporary-account-viewer"},
// 页面管理型权限
'abusefilter-helper': {list: [], class: "markrights-abusefilter-helper"},
'abusefilter': {list: [], class: "markrights-abusefilter"},
patroller: {list: [], class: "markrights-patroller"},
rollbacker: {list: [], class: "markrights-rollbacker"},
autoreviewer: {list: [], class: "markrights-autoreviewer"},
'event-organizer': {list: [], class: "markrights-event-organizer"},
// 大量操作型权限
accountcreator: {list: [], class: "markrights-accountcreator"},
'massmessage-sender': {list: [], class: "markrights-massmessage-sender"},
// 确认权限
confirmed: {list: [], class: "markrights-confirmed"},
autoconfirmed: {list: [], class: "markrights-autoconfirmed"},
extendedconfirmed: {list: [], class: "markrights-extendedconfirmed"},
// 机器权限
bot: {list: [], class: "markrights-bot"},
flood: {list: [], class: "markrights-flood"},
// IPBE
'ipblock-exempt': {list: [], class: "markrights-ipblock-exempt"},
// arbcom
arbcom: {list: [], class: "markrights-arbcom"},
// 安全投票相关权限
electionclerk: {list: [], class: "markrights-electionclerk"},
scrutineer: {list: [], class: "markrights-scrutineer"},
};
console.log('[MarkRights Debug] Initial groups configuration:', JSON.parse(JSON.stringify(groups)));
var userLinkSelector = 'a.mw-userlink, a.cs-comment-author';
var markRightsInProgress = false;
var debounceTimeout;
var markUG = function () {
if (markRightsInProgress) { return; }
markRightsInProgress = true;
console.log('[MarkRights Debug] Step 2: markUG function has been called for a global scan.');
var getUsernameFromUrl = function(url) {
if (!url) return null;
var match;
match = url.match(/\/(wiki\/)?User:([^/?#]+)/);
if (match && match[2]) {
try { return decodeURIComponent(match[2].replace(/_/g, ' ')); } catch (e) { return match[2].replace(/_/g, ' '); }
}
match = url.match(/title=User(?:%3A|:)([^&/#]+)/);
if (match && match[1]) {
try { return decodeURIComponent(match[1].replace(/_/g, ' ')); } catch (e) { return match[1].replace(/_/g, ' '); }
}
return null;
};
var done = function (isPreScan) {
var markedCount = 0;
$(userLinkSelector).each(function (i, el) {
var username = getUsernameFromUrl(el.href);
if (username) {
for (var group in groups) {
if (groups.hasOwnProperty(group) && groups[group].list.indexOf(username) > -1) {
if ($(el).children('sup.' + groups[group].class).length === 0) {
$(el).append('<sup class="' + groups[group].class + '"></sup>');
markedCount++;
}
}
}
}
});
if (markedCount > 0 && !isPreScan) {
console.log('[MarkRights Final Scan] Applied ' + markedCount + ' marks.');
}
};
var n;
var process = function (data) {
console.log('[MarkRights Debug] Step 7: Received API response.', data);
var users;
if (data.query && data.query.users) { users = data.query.users; } else { users = []; }
for (var i = 0; i < users.length; i++) {
var user = users[i];
if (user.groups) {
for (var group in groups) {
if (groups.hasOwnProperty(group) && user.groups.indexOf(group) > -1 && groups[group].list.indexOf(user.name) === -1) {
groups[group].list.push(user.name);
}
}
}
}
n--;
if (n <= 0) {
console.log('[MarkRights Debug] Step 8: All API requests complete. Starting final marking process.');
done(false);
markRightsInProgress = false;
}
};
var $users = $(userLinkSelector).not('.markrights-processed');
console.log('[MarkRights Debug] Step 3: Found ' + $users.length + ' new, unprocessed user links using strict selector.');
if ($users.length === 0) {
markRightsInProgress = false;
return;
}
var usersToQuery = {};
$users.each(function (index, link) {
$(link).addClass('markrights-processed');
var username = getUsernameFromUrl(link.href);
console.log('--- Checking link: ' + link.href + ' --- Parsed username: ' + username);
if (username && !username.includes('/')) {
console.log('Result: VALID. Adding to query list.');
if (!groups.autoconfirmed.list.includes(username)) {
usersToQuery[username] = true;
}
} else {
console.log('Result: SKIPPED. Reason: ' + (username ? 'Is a subpage' : 'Could not parse username'));
}
});
done(true);
var userCount = Object.keys(usersToQuery).length;
console.log('[MarkRights Debug] Step 4: Collected ' + userCount + ' unique new usernames for API query.', Object.keys(usersToQuery));
if (userCount === 0) {
markRightsInProgress = false;
return;
}
var queue1 = [], queue2 = [], i = 0;
n = 0;
for (var user in usersToQuery) {
queue1.push(user);
i++;
if (i === 50) { queue2.push(queue1); queue1 = []; n++; i = 0; }
}
if (queue1.length > 0) { queue2.push(queue1); n++; }
console.log('[MarkRights Debug] Step 5: New usernames batched into ' + n + ' API requests.', queue2);
var api = new mw.Api({ userAgent: 'Gadget-MarkRights' });
for (var j = 0; j < queue2.length; j++) {
console.log('[MarkRights Debug] Step 6: Sending API request for batch ' + (j + 1) + '/' + queue2.length);
api.get({ format: 'json', action: 'query', list: 'users', usprop: 'groups', ususers: queue2[j].join('|') }).done(process).fail(function() { n--; if (n <= 0) { done(false); markRightsInProgress = false; } });
}
};
var triggerMarkUG = function() {
clearTimeout(debounceTimeout);
debounceTimeout = setTimeout(markUG, 100);
};
mw.hook('wikipage.content').add(function() {
console.log('[MarkRights Debug] Event: wikipage.content hook triggered.');
triggerMarkUG();
});
mw.hook('CommentStream.afterLoad').add(function() {
console.log('[MarkRights Debug] Event: CommentStream.afterLoad hook triggered!');
triggerMarkUG();
});
});