User:Xiplus/js/userRightsManager.js
< User:Xiplus | js
注意:保存之后,你必须清除浏览器缓存才能看到做出的更改。Google Chrome、Firefox、Microsoft Edge及Safari:按住⇧ Shift键并单击工具栏的“刷新”按钮。参阅Help:绕过浏览器缓存以获取更多帮助。
/* global Morebits */
/* eslint-disable no-extra-boolean-cast */
// <nowiki>
// Some UI code adapted from [[User:Mr. Stradivarius/gadgets/Draftify.js]]
// Adapted from https://en.wikipedia.org/wiki/User:MusikAnimal/userRightsManager.js
(function() {
var pagePermissions = {
'Wikipedia:權限申請/申請IP封禁豁免權': 'ipblock-exempt',
'Wikipedia:權限申請/申請巡查權': 'patroller',
'Wikipedia:權限申請/申請回退權': 'rollbacker',
'Wikipedia:權限申請/申請巡查豁免權': 'autoreviewer',
'Wikipedia:權限申請/申請確認用戶權': 'confirmed',
'Wikipedia:權限申請/申請大量訊息發送權': 'massmessage-sender',
'Wikipedia:權限申請/申請大量帳號建立權': 'accountcreator',
'Wikipedia:權限申請/申請檔案移動權': 'filemover',
'Wikipedia:權限申請/申請跨維基導入權': 'transwiki',
'Wikipedia:權限申請/申請模板編輯權': 'templateeditor',
}
var pageName = mw.config.get('wgPageName');
var permission = pagePermissions[pageName];
if (!permission) {
return;
}
if (permission === 'accountcreator' && mw.config.get('wgUserGroups').indexOf('bureaucrat') === -1) {
return;
}
var templates = {
'ipblock-exempt': 'Ipexemptgranted',
'patroller': 'Patrolgranted',
'rollbacker': 'Rollbackgranted',
'autoreviewer': 'Autopatrolgranted',
'massmessage-sender': 'MMSgranted',
'templateeditor': 'Template editor granted',
};
var api,
tagLine = '(使用[[User:Xiplus/js/userRightsManager|userRightsManager]])',
permaLink, userName, dialog, permissionNames;
mw.loader.using(['oojs-ui', 'mediawiki.api', 'mediawiki.widgets.SelectWithInputWidget', 'mediawiki.widgets.expiry', 'ext.gadget.morebits', 'ext.gadget.site-lib'], function() {
permissionNames = {
'ipblock-exempt': wgULS('IP封禁豁免', 'IP封鎖例外'),
'patroller': wgULS('巡查员', '巡查員'),
'rollbacker': wgULS('回退员', '回退員'),
'autoreviewer': '巡查豁免者',
'confirmed': wgULS('已确认的用户', '已確認的使用者'),
'massmessage-sender': wgULS('大量消息发送者', '大量訊息傳送者'),
'accountcreator': wgULS('大量账户创建者', '大量帳號建立者'),
'filemover': wgULS('文件移动员', '檔案移動員'),
'transwiki': wgULS('跨维基导入者', '跨維基匯入者'),
'templateeditor': wgULS('模板编辑员', '模板編輯員'),
};
api = new mw.Api();
$('.perm-assign-permissions a').on('click', function(e) {
if (permission === 'AutoWikiBrowser') return true;
e.preventDefault();
userName = mw.util.getParamValue('user', $(this).attr('href'));
showDialog();
});
});
function showDialog() {
var Dialog = function(config) {
Dialog.super.call(this, config);
};
OO.inheritClass(Dialog, OO.ui.ProcessDialog);
Dialog.static.name = 'user-rights-manager';
Dialog.static.title = '授予' + permissionNames[permission] + wgULS('给', '給') + userName;
Dialog.static.actions = [
{ action: 'submit', label: wgULS('授权', '授權'), flags: ['primary', 'progressive'] },
{ label: '取消', flags: 'safe' },
];
Dialog.prototype.getApiManager = function() {
return this.apiManager;
};
Dialog.prototype.getBodyHeight = function() {
return 255;
};
Dialog.prototype.initialize = function() {
Dialog.super.prototype.initialize.call(this);
this.editPanel = new OO.ui.PanelLayout({
expanded: false,
});
var rightLogWapper = $('<span>');
var url = mw.util.getUrl('Special:Log/rights', { type: 'rights', page: 'User:' + userName });
$('<a>').text(wgULS('最近权限日志', '最近權限日誌')).attr({ 'href': url, 'target': '_blank' }).appendTo(rightLogWapper);
rightLogWapper.append(':');
var rightLogText = $('<span>').text(wgULS('获取中', '取得中')).appendTo(rightLogWapper);
this.rightLog = new OO.ui.LabelWidget({
label: rightLogWapper,
});
this.editPanel.$element.append(this.rightLog.$element);
api.get({
action: 'query',
format: 'json',
list: 'logevents',
leaction: 'rights/rights',
letitle: 'User:' + userName,
lelimit: '1',
}).done(function(data) {
var logs = data.query.logevents;
if (logs.length === 0) {
rightLogText.text(wgULS('没有任何日志', '沒有任何日誌'));
} else {
var timestamp = new Morebits.date(logs[0].timestamp).calendar();
var rights = logs[0].params.newgroups.join('、') || wgULS('(无)', '(無)');
rightLogText.text(timestamp + ' ' + logs[0].user + wgULS('将用户组改为', '將使用者群組改為') + rights);
}
});
this.editFieldset = new OO.ui.FieldsetLayout({
classes: ['container'],
});
this.editPanel.$element.append(this.editFieldset.$element);
this.rightsChangeSummaryInput = new OO.ui.TextInputWidget({
value: '',
placeholder: '可留空',
});
this.expiryInput = new mw.widgets.ExpiryWidget({
$overlay: $('.oo-ui-window'),
RelativeInputClass: mw.widgets.SelectWithInputWidget,
relativeInput: {
or: true,
dropdowninput: {
options: [
{ data: '1 day', label: '1天' },
{ data: '1 week', label: wgULS('1周', '1週') },
{ data: '1 month', label: wgULS('1个月', '1個月') },
{ data: '3 months', label: wgULS('3个月', '3個月') },
{ data: '6 months', label: wgULS('6个月', '6個月') },
{ data: '1 year', label: '1年' },
{ data: 'infinite', label: wgULS('没有期限', '沒有期限') },
{ data: 'other', label: wgULS('其他时间', '其他時間') },
],
value: 'infinite',
},
textinput: {
required: true,
},
},
});
this.closingRemarksInput = new OO.ui.TextInputWidget({
value: '{{done}}--~~~~',
});
this.watchTalkPageCheckbox = new OO.ui.CheckboxInputWidget({
selected: false,
});
var formElements = [
new OO.ui.FieldLayout(this.rightsChangeSummaryInput, {
label: wgULS('授权原因', '授權原因'),
}),
new OO.ui.FieldLayout(this.expiryInput, {
label: wgULS('结束时间', '結束時間'),
}),
new OO.ui.FieldLayout(this.closingRemarksInput, {
label: wgULS('关闭请求留言', '關閉請求留言'),
}),
];
if (!!templates[permission]) {
formElements.push(
new OO.ui.FieldLayout(this.watchTalkPageCheckbox, {
label: wgULS('监视用户讨论页', '監視使用者討論頁'),
})
);
}
this.editFieldset.addItems(formElements);
this.submitPanel = new OO.ui.PanelLayout({
$: this.$,
expanded: false,
});
this.submitFieldset = new OO.ui.FieldsetLayout({
classes: ['container'],
});
this.submitPanel.$element.append(this.submitFieldset.$element);
this.changeRightsProgressLabel = new OO.ui.LabelWidget();
this.changeRightsProgressField = new OO.ui.FieldLayout(this.changeRightsProgressLabel);
this.markAsDoneProgressLabel = new OO.ui.LabelWidget();
this.markAsDoneProgressField = new OO.ui.FieldLayout(this.markAsDoneProgressLabel);
this.issueTemplateProgressLabel = new OO.ui.LabelWidget();
this.issueTemplateProgressField = new OO.ui.FieldLayout(this.issueTemplateProgressLabel);
this.stackLayout = new OO.ui.StackLayout({
items: [this.editPanel, this.submitPanel],
padded: true,
});
this.$body.append(this.stackLayout.$element);
};
Dialog.prototype.onSubmit = function() {
var self = this, promiseCount = !!templates[permission] ? 3 : 2;
self.actions.setAbilities({ submit: false });
var addPromise = function(field, promise) {
self.pushPending();
promise.done(function() {
field.$field.append($('<span>')
.text('完成!')
.prop('style', 'position:relative; top:0.5em; color: #009000; font-weight: bold')
);
}).fail(function(obj) {
if (obj && obj.error && obj.error.info) {
field.$field.append($('<span>')
.text(wgULS('错误:', '錯誤:') + obj.error.info)
.prop('style', 'position:relative; top:0.5em; color: #cc0000; font-weight: bold')
);
} else {
field.$field.append($('<span>')
.text(wgULS('发生未知错误。', '發生未知錯誤。'))
.prop('style', 'position:relative; top:0.5em; color: #cc0000; font-weight: bold')
);
}
}).always(function() {
promiseCount--; // FIXME: maybe we could use a self.isPending() or something
self.popPending();
if (promiseCount === 0) {
setTimeout(function() {
location.reload(true);
}, 1000);
}
});
return promise;
};
self.markAsDoneProgressField.setLabel(wgULS('标记请求为已完成...', '標記請求為已完成...'));
self.submitFieldset.addItems([self.markAsDoneProgressField]);
self.changeRightsProgressField.setLabel(wgULS('授予权限...', '授予權限...'));
self.submitFieldset.addItems([self.changeRightsProgressField]);
if (!!templates[permission]) {
self.issueTemplateProgressField.setLabel(wgULS('发送通知...', '發送通知...'));
self.submitFieldset.addItems([self.issueTemplateProgressField]);
}
addPromise(
self.markAsDoneProgressField,
markAsDone('\n:' + this.closingRemarksInput.getValue())
).then(function(data) {
addPromise(
self.changeRightsProgressField,
assignPermission(
this.rightsChangeSummaryInput.getValue(),
data.edit.newrevid,
this.expiryInput.getValue()
)
).then(function() {
if (!!templates[permission]) {
addPromise(
self.issueTemplateProgressField,
issueTemplate(this.watchTalkPageCheckbox.isSelected())
);
}
}.bind(this));
}.bind(this));
self.stackLayout.setItem(self.submitPanel);
};
Dialog.prototype.getActionProcess = function(action) {
return Dialog.super.prototype.getActionProcess.call(this, action).next(function() {
if (action === 'submit') {
return this.onSubmit();
} else {
return Dialog.super.prototype.getActionProcess.call(this, action);
}
}, this);
};
dialog = new Dialog({
size: 'medium',
});
var windowManager = new OO.ui.WindowManager();
$('body').append(windowManager.$element);
windowManager.addWindows([dialog]);
windowManager.openWindow(dialog);
}
function assignPermission(summary, revId, expiry) {
if (expiry === '') {
expiry = 'infinite';
}
var removePermission = '';
if (permission === 'patroller' && expiry === 'infinite') {
removePermission = 'autoreviewer';
}
permaLink = '[[Special:PermaLink/' + revId + '#User:' + userName + '|' + wgULS('权限申请', '權限申請') + ']]';
var fullSummary = '+' + permissionNames[permission] + ';' + permaLink;
if (summary !== '') {
fullSummary += ';' + summary;
}
fullSummary += tagLine;
return api.postWithToken('userrights', {
action: 'userrights',
format: 'json',
user: userName.replace(/ /g, '_'),
add: permission,
remove: removePermission,
reason: fullSummary,
expiry: expiry,
});
}
function markAsDone(closingRemarks) {
var sectionNode = document.getElementById('User:' + userName.replace(/"/g, '.22').replace(/ /g, '_')),
sectionNumber = $(sectionNode).siblings('.mw-editsection').find("a:not('.mw-editsection-visualeditor')").prop('href').match(/section=(\d+)/)[1];
var basetimestamp, curtimestamp, page, revision, content;
return api.get({
action: 'query',
prop: 'revisions',
rvprop: ['content', 'timestamp'],
titles: [pageName],
rvsection: sectionNumber,
formatversion: '2',
curtimestamp: true,
})
.then(function(data) {
if (!data.query || !data.query.pages) {
return $.Deferred().reject('unknown');
}
page = data.query.pages[0];
if (!page || page.invalid) {
return $.Deferred().reject('invalidtitle');
}
if (page.missing) {
return $.Deferred().reject('nocreate-missing');
}
revision = page.revisions[0];
basetimestamp = revision.timestamp;
curtimestamp = data.curtimestamp;
content = revision.content;
})
.then(function() {
content = content.trim();
content = content.replace(/(:\s*{{Status)(\|.*?)?}}/i, '$1|+}}');
content += closingRemarks;
return api.postWithEditToken({
action: 'edit',
title: pageName,
section: sectionNumber,
text: content,
summary: '/* User:' + userName + ' */ 完成' + tagLine,
formatversion: '2',
assert: mw.config.get('wgUserName') ? 'user' : undefined,
basetimestamp: basetimestamp,
starttimestamp: curtimestamp,
nocreate: true,
});
});
}
function issueTemplate(watch) {
var talkPage = 'User talk:' + userName.replace(/ /g, '_');
var message = '{{subst:' + templates[permission] + '}}';
return api.get({
action: 'query',
prop: 'info',
titles: talkPage,
}).then(function(data) {
var page = Object.values(data.query.pages)[0];
if (page.missing !== undefined) {
return api.create(
talkPage,
{
summary: wgULS('根据', '根據') + permaLink + '授予' + permissionNames[permission] + tagLine,
watchlist: watch ? 'watch' : 'unwatch',
},
message
);
} else if (page.contentmodel == 'flow-board') {
return api.postWithEditToken({
action: 'flow',
page: talkPage,
submodule: 'new-topic',
nttopic: wgULS('根据', '根據') + permaLink + '授予' + permissionNames[permission],
ntcontent: message,
ntformat: 'wikitext',
});
} else {
return api.edit(talkPage, function(revision) {
return {
text: (revision.content + '\n\n' + message).trim(),
summary: wgULS('根据', '根據') + permaLink + '授予' + permissionNames[permission] + tagLine,
watchlist: watch ? 'watch' : 'unwatch',
};
});
}
});
}
})();
// </nowiki>