User:Kiteretsu/js/all-in-one.js
Jump to navigation
Jump to search
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.
/* Rollback, block, (revision) delete, and ignore.
*
* For more info: https://meta.wikimedia.org/wiki/User:WhitePhosphorus/all-in-one
*
* See also https://zh.wikipedia.org/wiki/User:WhitePhosphorus/js/all-in-one.js
* which is a legacy script.
*/
$(function () {
mw.loader.using(['mediawiki.util', 'mediawiki.api', 'oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows'], function() {
let config = {};
let inited = false;
let loaded = false;
let windowManager = new OO.ui.WindowManager();
let aio_dialog;
const work = function() {
let api = new mw.Api();
if (config.block) {
let data = {
action: 'block',
user: config.username,
expiry: config.blockDur,
reason: config.blockReason
};
if (config.blockAnon) data.anononly = 1;
if (config.blockAuto) data.autoblock = 1;
if (config.blockCreate) data.nocreate = 1;
if (!config.blockTalk) data.allowusertalk = 1;
if (config.blockMail) data.noemail = 1;
if (config.blockHide) data.hidename = 1;
api.postWithEditToken(data).done(() => mw.notify('The villain is blocked.')).fail(function(e) {
mw.notify('Failed to block the villain: ' + e, { type: 'warn' });
console.log(e);
});
}
let untildate = new Date();
if (config.endtime === 'inf') {
untildate = null;
} else {
untildate.setSeconds(untildate.getSeconds() - parseInt(config.endtime));
}
data = {
action: 'query',
list: 'usercontribs',
ucuser: config.username,
uclimit: 'max'
// TODO: continue
};
if (untildate) data.ucend = untildate.toISOString();
api.get(data).done(function(data) {
let contribs = data.query;
if (!contribs) {
mw.notify('Failed to fetch the contribs!', { type: 'warn' });
return;
}
contribs = contribs.usercontribs;
if (!contribs || !contribs.length) {
mw.notify('No contribs found.');
return;
}
let ids = {};
let creation = [];
for (let edit of contribs) {
if (edit.new === '') {
creation.push(edit.title);
} else {
if (ids[edit.title] === undefined) ids[edit.title] = [];
ids[edit.title].push(edit.revid);
}
}
for (let [title, idlist] of Object.entries(ids)) {
if (!config.rollback) {
// only check revdel
if (config.rd) {
api.postWithEditToken({
action: 'revisiondelete',
type: 'revision',
ids: idlist,
hide: config.rdHides,
reason: config.rdReason,
suppress: config.os ? "yes" : "nochange"
}).done(() => mw.notify(`${idlist.length} revisions on page ${title} hidden.`)).fail(function(e) {
mw.notify(`Failed to hide revisions on ${title}: ${e}`, { type: 'warn' });
console.log('revisiondelete', title, idlist, e);
});
}
continue;
}
// we'd like to rollback first then revdel - if not, attempts to revdel the content may fail
data = config.rollbackBot ? {markbot: 1} : {};
data.summary = config.rollbackShow ? '' : 'revert edits by <username hidden>';
api.rollback(title, config.username, data).done(function() {
mw.notify(`Page ${title} Reverted.`);
}).fail(function(e) {
mw.notify(`Failed to revert on the page ${title}: ${e}`, { type: 'warn' });
console.log('revert', title, e);
}).always(function() {
if (config.rd) {
api.postWithEditToken({
action: 'revisiondelete',
type: 'revision',
ids: idlist,
hide: config.rdHides,
reason: config.rdReason,
suppress: config.os ? "yes" : "nochange"
}).done(() => mw.notify(`${idlist.length} revisions on page ${title} hidden.`)).fail(function(e) {
mw.notify(`Failed to hide revisions on ${title}: ${e}`, { type: 'warn' });
console.log('revisiondelete', title, idlist, e);
});
}
});
}
if (config.massdel) {
for (let title of creation) {
api.postWithEditToken({
action: 'delete',
title: title,
reason: config.massdelReason
}).done(() => mw.notify(`Deleted page ${title}.`)).fail(function(e) {
mw.notify(`Failed to delete ${title}: ${e}`, { type: 'warn' });
console.log('delete', title, e);
});
}
}
});
};
// Build OOUI interface
const init = function() {
if (inited) return;
inited = true;
function AIODialog(config) {
AIODialog.super.call(this, config);
}
OO.inheritClass(AIODialog, OO.ui.ProcessDialog);
AIODialog.static.name = 'p4AIODialog';
AIODialog.static.actions = [
{
flags: ['primary', 'destructive'],
label: 'Start [enter]',
action: 'start',
},
{
flags: ['safe', 'close'],
},
];
AIODialog.prototype.initialize = function() {
AIODialog.super.prototype.initialize.call(this);
this.panel = new OO.ui.PanelLayout({
classes: ['p4-aio-form'],
padded: true,
expanded: false,
});
// General info: username, package, etc.
this.top_fieldset = new OO.ui.FieldsetLayout({
label: 'All in One',
});
this.top_username_input = new OO.ui.TextInputWidget({
placeholder: 'username or IP (not range)',
});
this.top_endtime_dropdown = new OO.ui.DropdownWidget({
menu: {
items: [
new OO.ui.MenuOptionWidget({
data: 3600,
label: 'in 1 hour',
}),
new OO.ui.MenuOptionWidget({
data: 86400,
label: 'in 1 day',
}),
new OO.ui.MenuOptionWidget({
data: 'inf',
label: 'everything',
}),
new OO.ui.MenuOptionWidget({
data: 'other',
label: 'Other: (in seconds)',
}),
],
},
});
this.top_endtime_input = new OO.ui.TextInputWidget({
placeholder: 'newer than ... seconds',
});
this.top_package_dropdown = new OO.ui.DropdownWidget();
this.top_suffix_dropdown = new OO.ui.DropdownWidget({
menu: {
items: [ new OO.ui.MenuOptionWidget({ data: '', label: '<no suffix>' }) ],
},
});
this.top_fieldset.addItems([
new OO.ui.FieldLayout(
this.top_username_input, {
label: 'Target',
}
),
new OO.ui.FieldLayout(
new OO.ui.Widget({
content: [
this.top_endtime_dropdown,
this.top_endtime_input,
]
}), {
label: 'Edits',
}
),
new OO.ui.FieldLayout(
this.top_package_dropdown, {
label: 'Package',
help: new OO.ui.HtmlSnippet(
'<a href="https://meta.wikimedia.org/wiki/User:WhitePhosphorus/all-in-one#Add_your_own_package">how to define your packages?</a>'
),
}
),
new OO.ui.FieldLayout(
this.top_suffix_dropdown, {
label: 'Suffix',
help: new OO.ui.HtmlSnippet(
'<a href="https://meta.wikimedia.org/wiki/User:WhitePhosphorus/all-in-one#Add_your_reasons_in_drop_down_list">how to define your rationales and suffixes?</a>'
),
}
),
]);
// Rollback
this.rollback_fieldset = new OO.ui.FieldsetLayout({
label: 'Rollback',
invisibleLabel: true,
classes: ['p4-aio-rollback-fieldset'],
});
this.rollback_checkbox = new OO.ui.CheckboxInputWidget({ selected: true });
this.rollback_bot_checkbox = new OO.ui.CheckboxInputWidget({ selected: true });
this.rollback_showname_checkbox = new OO.ui.CheckboxInputWidget({ selected: true });
this.rollback_fieldset.addItems([
new OO.ui.FieldLayout(
this.rollback_checkbox, {
label: 'Enable rollback',
align: 'inline',
classes: ['p4-aio-checkbox', 'p4-aio-checkbox-block'],
}
),
new OO.ui.FieldLayout(
this.rollback_bot_checkbox, {
label: 'Mark rollback as bot edits',
align: 'inline',
classes: ['p4-aio-checkbox'],
}
),
new OO.ui.FieldLayout(
this.rollback_showname_checkbox, {
label: 'Show username in rollback summary',
align: 'inline',
help: 'For some vandals with inappropriate username, you may want to uncheck this and the revert summary will look like "revert edits by <username hidden>".',
classes: ['p4-aio-checkbox'],
}
),
]);
// Block
this.block_fieldset = new OO.ui.FieldsetLayout({
label: 'Block',
invisibleLabel: true,
classes: ['p4-aio-block-fieldset'],
});
this.block_duration_dropdown = new OO.ui.DropdownWidget({
menu: {
items: [
new OO.ui.MenuOptionWidget({ data: '1 day', label: '1 day' }),
new OO.ui.MenuOptionWidget({ data: '31 hours', label: '31 hours' }),
new OO.ui.MenuOptionWidget({ data: '3 days', label: '3 days' }),
new OO.ui.MenuOptionWidget({ data: '5 days', label: '5 days' }),
new OO.ui.MenuOptionWidget({ data: '1 week', label: '1 week' }),
new OO.ui.MenuOptionWidget({ data: '2 weeks', label: '2 weeks' }),
new OO.ui.MenuOptionWidget({ data: '1 month', label: '1 month' }),
new OO.ui.MenuOptionWidget({ data: '3 months', label: '3 months' }),
new OO.ui.MenuOptionWidget({ data: '6 months', label: '6 months' }),
new OO.ui.MenuOptionWidget({ data: '1 year', label: '1 year' }),
new OO.ui.MenuOptionWidget({ data: '2 years', label: '2 years' }),
new OO.ui.MenuOptionWidget({ data: 'never', label: 'indefinite' }),
new OO.ui.MenuOptionWidget({ data: 'other', label: 'Other:' }),
],
},
});
this.block_duration_input = new OO.ui.TextInputWidget({
placeholder: 'duration/timestamp',
});
this.block_reason_dropdown = new OO.ui.DropdownWidget({
menu: {
// Data for "Other:" must be empty, since it will be directly included in the actual block reason
// Same for the (revision) delete reasons (will be added to the input box if append button is clicked)
items: [ new OO.ui.MenuOptionWidget({ data: '', label: 'Other:' }) ],
},
});
this.block_reason_input = new OO.ui.TextInputWidget({
placeholder: 'other rationale to append',
});
this.block_checkbox = new OO.ui.CheckboxInputWidget({ selected: true });
this.block_hardblock_checkbox = new OO.ui.CheckboxInputWidget();
this.block_autoblock_checkbox = new OO.ui.CheckboxInputWidget({ selected: true });
this.block_create_checkbox = new OO.ui.CheckboxInputWidget({ selected: true });
this.block_talk_checkbox = new OO.ui.CheckboxInputWidget({ selected: true });
this.block_mail_checkbox = new OO.ui.CheckboxInputWidget({ selected: true });
this.block_hidename_checkbox = new OO.ui.CheckboxInputWidget();
this.block_fieldset.addItems([
new OO.ui.FieldLayout(
this.block_checkbox, {
label: 'Enable block',
align: 'inline',
classes: ['p4-aio-checkbox', 'p4-aio-checkbox-block'],
}
),
new OO.ui.FieldLayout(
new OO.ui.Widget({
content: [
this.block_duration_dropdown,
this.block_duration_input,
]
}), {
label: 'Expiration',
}
),
new OO.ui.FieldLayout(
new OO.ui.Widget({
content: [
this.block_reason_dropdown,
this.block_reason_input,
]
}), {
label: 'Reason',
}
),
new OO.ui.FieldLayout(
this.block_hardblock_checkbox, {
label: 'Hard block',
align: 'inline',
help: 'Apply block to logged-in users from this IP address',
classes: ['p4-aio-checkbox', 'p4-aio-anon-only'],
}
),
new OO.ui.FieldLayout(
this.block_autoblock_checkbox, {
label: 'Auto block',
align: 'inline',
help: 'Automatically block the last IP address used by this user, and any subsequent IP addresses they try to edit from, for a period of 1 day',
classes: ['p4-aio-checkbox', 'p4-aio-reg-only'],
}
),
new OO.ui.FieldLayout(
this.block_create_checkbox, {
label: 'Block account creation',
align: 'inline',
classes: ['p4-aio-checkbox'],
}
),
new OO.ui.FieldLayout(
this.block_talk_checkbox, {
label: 'Block editing own talk page',
align: 'inline',
classes: ['p4-aio-checkbox'],
}
),
new OO.ui.FieldLayout(
this.block_mail_checkbox, {
label: 'Block email',
align: 'inline',
classes: ['p4-aio-checkbox'],
}
),
new OO.ui.FieldLayout(
this.block_hidename_checkbox, {
label: 'Hide username from public logs',
align: 'inline',
help: 'needs "hideuser" right, or your action will fail',
classes: ['p4-aio-checkbox'],
}
),
]);
// Page deletion
this.pagedelete_fieldset = new OO.ui.FieldsetLayout({
label: 'Page deletion',
invisibleLabel: true,
classes: ['p4-aio-pagedelete-fieldset'],
});
this.pagedelete_checkbox = new OO.ui.CheckboxInputWidget({ selected: true });
this.pagedelete_reason_dropdown = new OO.ui.DropdownWidget({
menu: {
items: [ new OO.ui.MenuOptionWidget({ data: '', label: 'Other:' }) ],
},
});
this.pagedelete_reason_button = new OO.ui.ButtonWidget({ label: 'Append' });
this.pagedelete_reason_input = new OO.ui.TextInputWidget({
placeholder: 'full rationale to submit',
});
this.pagedelete_fieldset.addItems([
new OO.ui.FieldLayout(
this.pagedelete_checkbox, {
label: 'Enable deletion',
align: 'inline',
classes: ['p4-aio-checkbox', 'p4-aio-checkbox-block'],
}
),
new OO.ui.FieldLayout(
new OO.ui.Widget({
content: [
this.pagedelete_reason_dropdown,
this.pagedelete_reason_button,
this.pagedelete_reason_input,
]
}), {
label: 'Reason',
classes: ['p4-aio-reason'],
}
),
]);
// Revision deletion
this.revisiondelete_fieldset = new OO.ui.FieldsetLayout({
label: 'Revision deletion',
invisibleLabel: true,
classes: ['p4-aio-revisiondelete-fieldset'],
});
this.revisiondelete_checkbox = new OO.ui.CheckboxInputWidget({ selected: true });
this.revisiondelete_content_checkbox = new OO.ui.CheckboxInputWidget({ selected: true });
this.revisiondelete_summary_checkbox = new OO.ui.CheckboxInputWidget({ selected: true });
this.revisiondelete_username_checkbox = new OO.ui.CheckboxInputWidget();
this.revisiondelete_oversight_checkbox = new OO.ui.CheckboxInputWidget();
this.revisiondelete_reason_dropdown = new OO.ui.DropdownWidget({
menu: {
items: [ new OO.ui.MenuOptionWidget({ data: '', label: 'Other:' }) ],
},
});
this.revisiondelete_reason_button = new OO.ui.ButtonWidget({ label: 'Append' });
this.revisiondelete_reason_input = new OO.ui.TextInputWidget({
placeholder: 'full rationale to submit',
});
this.revisiondelete_fieldset.addItems([
new OO.ui.FieldLayout(
this.revisiondelete_checkbox, {
label: 'Enable revision deletion',
align: 'inline',
classes: ['p4-aio-checkbox', 'p4-aio-checkbox-block'],
}
),
new OO.ui.FieldLayout(
this.revisiondelete_content_checkbox, {
label: 'Hide revision content',
align: 'inline',
classes: ['p4-aio-checkbox'],
}
),
new OO.ui.FieldLayout(
this.revisiondelete_summary_checkbox, {
label: 'Hide summaries',
align: 'inline',
classes: ['p4-aio-checkbox'],
}
),
new OO.ui.FieldLayout(
this.revisiondelete_username_checkbox, {
label: 'Hide username',
align: 'inline',
classes: ['p4-aio-checkbox'],
}
),
new OO.ui.FieldLayout(
this.revisiondelete_oversight_checkbox, {
label: 'Oversight',
align: 'inline',
help: 'needs "suppressrevision" right, or your action will fail',
classes: ['p4-aio-checkbox'],
}
),
new OO.ui.FieldLayout(
new OO.ui.Widget({
content: [
this.revisiondelete_reason_dropdown,
this.revisiondelete_reason_button,
this.revisiondelete_reason_input,
]
}), {
label: 'Reason',
classes: ['p4-aio-reason'],
}
),
]);
// Update here if new fieldsets are introduced
for (let content of [
this.top_fieldset, this.rollback_fieldset, this.block_fieldset,
this.pagedelete_fieldset, this.revisiondelete_fieldset,
]) {
this.panel.$element.append(content.$element);
}
this.$body.append(this.panel.$element);
// CSS styles
// Make checkboxes stay in the same line if possible ...
$('.p4-aio-checkbox').css({
display: 'inline-block',
'margin-right': '12px',
// workaround: the height of checkboxes with a tooltip are different from those without one
// thus set height of every checkbox to 21px to align them
height: '21px',
});
// ... except those marked as block
$('.p4-aio-checkbox.p4-aio-checkbox-block').css({
display: 'block',
'font-weight': 'bold',
});
// The header consumes too much space by default (40%)
$('.p4-aio-form .oo-ui-fieldLayout-align-left .oo-ui-fieldLayout-header').css({
width: '20%',
});
$('.p4-aio-form .oo-ui-fieldLayout-align-left .oo-ui-fieldLayout-field').css({
width: '80%',
});
// Border for rollback, block, etc.
$('.p4-aio-form .oo-ui-fieldsetLayout:nth-child(n+2)').css({
border: '1px solid #a2a9b1',
'border-radius': '2px',
padding: '12px',
});
// Make the button nowrap in reason fields and the text input be in the new line
$('.p4-aio-reason .oo-ui-fieldLayout-field > .oo-ui-widget').css({
display: 'flex',
'flex-wrap': 'wrap',
});
$('.p4-aio-reason .oo-ui-fieldLayout-field > .oo-ui-widget > .oo-ui-dropdownWidget').css({
'flex-basis': 0,
'flex-grow': 1,
});
$('.p4-aio-reason .oo-ui-fieldLayout-field > .oo-ui-widget > .oo-ui-buttonWidget').css({
'margin-right': 0,
});
$('.p4-aio-reason .oo-ui-fieldLayout-field > .oo-ui-widget > .oo-ui-textInputWidget').css({
'flex-basis': '100%',
});
}
AIODialog.prototype.getActionProcess = function(action) {
if (action === 'start') {
return new OO.ui.Process(function() {
// Load config
config.username = this.top_username_input.getValue();
if (!config.username) return;
config.suffix = this.top_suffix_dropdown.getMenu().findSelectedItem().getData();
config.isIP = mw.util.isIPAddress(config.username);
config.endtime = getValueFromDropdownAndInput('top_endtime');
config.rollback = this.rollback_checkbox.isSelected();
config.rollbackBot = this.rollback_bot_checkbox.isSelected();
config.rollbackShow = this.rollback_showname_checkbox.isSelected();
config.block = this.block_checkbox.isSelected();
config.blockDur = getValueFromDropdownAndInput('block_duration');
config.blockReason = getValueFromDropdownAndInput('block_reason', other_data = '', check_include = true);
config.blockReason += config.suffix;
config.blockAnon = config.isIP && !this.block_hardblock_checkbox.isSelected();
config.blockAuto = !config.isIP && this.block_autoblock_checkbox.isSelected();
config.blockCreate = this.block_create_checkbox.isSelected();
config.blockTalk = this.block_talk_checkbox.isSelected();
config.blockMail = this.block_mail_checkbox.isSelected();
config.blockHide = this.block_hidename_checkbox.isSelected();
config.massdel = this.pagedelete_checkbox.isSelected();
config.massdelReason = getValueFromDropdownAndInput('pagedelete_reason', other_data = '', check_include = true);
config.massdelReason += config.suffix;
config.rd = this.revisiondelete_checkbox.isSelected();
config.rdHides = '';
if (this.revisiondelete_content_checkbox.isSelected()) config.rdHides += 'content|';
if (this.revisiondelete_summary_checkbox.isSelected()) config.rdHides += 'comment|';
if (this.revisiondelete_username_checkbox.isSelected()) config.rdHides += 'user|';
config.rdReason = getValueFromDropdownAndInput('revisiondelete_reason', other_data = '', check_include = true);
config.rdReason += config.suffix;
config.os = this.revisiondelete_oversight_checkbox.isSelected();
// Begin execution
work();
this.close();
}, this);
}
return AIODialog.super.prototype.getActionProcess.call(this, action);
};
// Set dialog width to be the same as its panel
AIODialog.prototype.getBodyWidth = function() {
return this.panel.$element.outerWidth(true);
};
$(document.body).append(windowManager.$element);
aio_dialog = new AIODialog({
size: 'large',
});
windowManager.addWindows([aio_dialog]);
}
// If `data` exists in dropdown, select it;
// else fill the input box and select "other" (provided by `other_data`)
const selectDropdownOrFillInput = function(field, data, other_data = 'other') {
let dropdown = aio_dialog[field + '_dropdown'];
let input = aio_dialog[field + '_input'];
if (!dropdown || !input) return;
let menu = dropdown.getMenu();
if (!menu) return;
menu.selectItemByData(data);
if (menu.findSelectedItem() === null) {
menu.selectItemByData(other_data);
input.setValue(data);
}
}
// If `data` selected is other, use the value from input box
const getValueFromDropdownAndInput = function(field, other_data = 'other', check_include = false) {
let dropdown = aio_dialog[field + '_dropdown'];
let input = aio_dialog[field + '_input'];
if (!dropdown || !input) return;
let menu = dropdown.getMenu();
if (!menu) return;
let selected = menu.findSelectedItem().getData();
let text = input.getValue();
if (check_include) {
if (text.includes(selected)) {
// Do not include reason in dropdown again
return text;
} else {
// Construct a reason like "dropdown: input"
return selected + (text ? ': ' + text : '');
}
}
return selected && selected === other_data ? text : selected;
}
$(mw.util.addPortletLink('p-cactions', '#', 'All-in-one')).click(function (e) {
init();
// Avoid re-loading config when user closed and opens the dialog again
if (loaded) {
windowManager.openWindow(aio_dialog, {});
return;
}
loaded = true;
aio_dialog.package_loaded = false;
if (typeof(p4js_all_in_one) !== 'object') p4js_all_in_one = {};
// load drop down reasons
let suffixes = p4js_all_in_one.suffixes || ["", " (global sysop action)", " (stewards action)"];
let reasons = p4js_all_in_one.reasons || {
block: ["Long-term abuse", "Vandalism-only account", "Spam-only account", "Open proxy", "Vandalism"],
pagedelete: ["Vandalism", "Spam"],
revisiondelete: ["Blatant offensive materials", "Violation of copyright policy", "Private information"],
};
for (let suffix of suffixes) {
if (!suffix) continue;
aio_dialog.top_suffix_dropdown.getMenu().addItems(new OO.ui.MenuOptionWidget({
data: suffix,
label: suffix,
}));
}
aio_dialog.top_suffix_dropdown.getMenu().addItems(
suffixes
.filter(e => e) // empty suffix is already included in dropdown
.map(e => new OO.ui.MenuOptionWidget({
data: e,
label: e,
}))
);
// Select the empty suffix by default
aio_dialog.top_suffix_dropdown.getMenu().selectItemByData('');
for (let action of ['block', 'pagedelete', 'revisiondelete']) {
aio_dialog[action + '_reason_dropdown'].getMenu().addItems(
(reasons[action] || []).map(e => new OO.ui.MenuOptionWidget({
data: e,
label: e,
})),
0 // Prepend to option list
);
}
// load packages (or the default one)
const default_package = {
tracingedits: {
duration: 3600,
indefregistered: true,
},
rollback: {
enabled: true,
bot: false,
showname: true,
},
block: {
enabled: true,
duration: "1 day",
indefregistered: true,
reason: "Vandalism",
autoblock: true,
hardblock: false,
create: true,
talk: false,
mail: false,
hidename: false,
},
pagedelete: {
enabled: true,
reason: "Vandalism",
},
revisiondelete: {
enabled: false,
content: true,
summary: true,
username: false,
reason: "Blatant offensive materials",
oversight: false,
},
};
let packages = p4js_all_in_one.packages || {};
if (!packages.Default) {
packages.Default = default_package;
}
aio_dialog.top_package_dropdown.getMenu().addItems(
Object.keys(packages).map(e => new OO.ui.MenuOptionWidget({
data: e,
label: e,
})),
0
);
// When dropdown changes (manually or automatically), decide whether to hide corresponding text input or not
for (let field of ['top_endtime', 'block_duration']) {
['choose', 'select'].forEach(e => aio_dialog[field + '_dropdown'].getMenu().on(e, function(item) {
aio_dialog[field + '_input'].toggle(item.getData() === 'other');
}));
}
// When package changes (manually or automatically), change various config
['choose', 'select'].forEach(e => aio_dialog.top_package_dropdown.getMenu().on(e, function(item) {
// Avoid config being changed when user closed and opens the dialog again
if (e == 'select' && aio_dialog.package_loaded) return;
aio_dialog.package_loaded = true;
let isIP = mw.util.isIPAddress(aio_dialog.top_username_input.getValue());
let pkg = packages[item.getData()] || {};
// checkboxes
for (let [action, action_config] of Object.entries(pkg)) {
for (let [item, item_enabled] of Object.entries(action_config)) {
if (typeof item_enabled === "boolean" && item !== "enabled" && item !== "indefregistered") {
aio_dialog[`${action}_${item}_checkbox`].setSelected(item_enabled);
}
}
}
// tracing edits
pkg.tracingedits = pkg.tracingedits || {};
selectDropdownOrFillInput('top_endtime', pkg.tracingedits.duration || 3600);
if (pkg.tracingedits.indefregistered && !isIP) {
aio_dialog.top_endtime_dropdown.getMenu().selectItemByData('inf');
}
// rollback: default is enabled
aio_dialog.rollback_checkbox.setSelected(pkg.rollback.enabled || true);
// block
pkg.block = pkg.block || {};
aio_dialog.block_checkbox.setSelected(pkg.block.enabled || false);
selectDropdownOrFillInput('block_duration', pkg.block.duration || '1 day');
if (pkg.tracingedits.indefregistered && !isIP) {
aio_dialog.block_duration_dropdown.getMenu().selectItemByData('never');
}
selectDropdownOrFillInput('block_reason', pkg.block.reason || 'Long-term abuse', '');
// page deletion
pkg.pagedelete = pkg.pagedelete || {};
aio_dialog.pagedelete_checkbox.setSelected(pkg.pagedelete.enabled || false);
selectDropdownOrFillInput('pagedelete_reason', pkg.pagedelete.reason || 'Vandalism', '');
// revision deletion
pkg.revisiondelete = pkg.revisiondelete || {};
aio_dialog.revisiondelete_checkbox.setSelected(pkg.revisiondelete.enabled || false);
selectDropdownOrFillInput('revisiondelete_reason', pkg.revisiondelete.reason || 'Hiding blatant offending materials', '');
}));
// select the default package
if (p4js_all_in_one.default_package && packages[p4js_all_in_one.default_package]) {
aio_dialog.top_package_dropdown.getMenu().selectItemByData(p4js_all_in_one.default_package);
} else {
aio_dialog.top_package_dropdown.getMenu().selectItemByData('Default');
}
// Append reasons
for (let action of ['pagedelete', 'revisiondelete']) {
aio_dialog[action + '_reason_button'].on('click', function() {
let text = aio_dialog[action + '_reason_input'].getValue();
aio_dialog[action + '_reason_input'].setValue(text + '; ' + aio_dialog[action + '_reason_dropdown'].getMenu().findSelectedItem().getData());
aio_dialog[action + '_reason_dropdown'].getMenu().selectItemByData('');
})
}
aio_dialog.top_username_input.on('change', function(username) {
let isIP = mw.util.isIPAddress(username);
let pkg = packages[aio_dialog.top_package_dropdown.getMenu().findSelectedItem().getData()] || default_package;
// Check indef
if (pkg.tracingedits && pkg.tracingedits.indefregistered && !isIP) {
aio_dialog.top_endtime_dropdown.getMenu().selectItemByData('inf');
aio_dialog.block_duration_dropdown.getMenu().selectItemByData('never');
} else {
pkg.tracingedits = pkg.tracingedits || {};
pkg.block = pkg.block || {};
selectDropdownOrFillInput('top_endtime', pkg.tracingedits.duration || 3600);
selectDropdownOrFillInput('block_duration', pkg.block.duration || '1 day');
}
// Anon block / registered user block settings
if (isIP) {
$('.p4-aio-reg-only').hide();
$('.p4-aio-anon-only').show();
} else {
$('.p4-aio-reg-only').show();
$('.p4-aio-anon-only').hide();
}
});
// Make fieldset transparent if not enabled
for (let action of ['rollback', 'block', 'pagedelete', 'revisiondelete']) {
aio_dialog[action + '_checkbox'].on('change', function(selected, _) {
$(`.p4-aio-${action}-fieldset`).css({
opacity: selected ? '100%': '50%',
});
});
// Initialize
$(`.p4-aio-${action}-fieldset`).css({
opacity: aio_dialog[action + '_checkbox'].isSelected() ? '100%': '50%',
transition: 'opacity 0.3s',
});
}
// enter to submit
$(document).on("keyup", event => {
if(event.key !== "Enter" || !aio_dialog.isOpened()) return;
aio_dialog.executeAction('start');
event.preventDefault();
});
// fill the current username if applicable
aio_dialog.top_username_input.setValue(mw.config.get('wgRelevantUserName') || '');
aio_dialog.top_username_input.focus();
windowManager.openWindow(aio_dialog, {});
});
});
});