//<nowiki>
mw.loader.using(['mediawiki.api', 'mediawiki.util', 'mediawiki.widgets', 'oojs-ui'], function () {
'use strict';
const page = mw.config.get('wgPageName').replace(/_/g, ' ');
const user = mw.config.get('wgUserName');
const prefsPage = `User:${user}/ProtectedPages.json`;
const prefs = { protected: [] };
let api = new mw.Api();
let token = null;
async function loadPrefs() {
try {
const res = await api.get({
action: 'query',
format: 'json',
prop: 'revisions',
titles: prefsPage,
rvprop: 'content',
origin: '*'
});
const pages = res.query.pages;
const data = pages[Object.keys(pages)[0]];
if (data.revisions && data.revisions[0]) {
Object.assign(prefs, JSON.parse(data.revisions[0]['*']));
}
} catch (e) {
alert('Failed to load preferences.');
}
}
async function getToken() {
try {
const res = await api.get({
action: 'query',
meta: 'tokens',
type: 'csrf'
});
token = res.query.tokens.csrftoken;
} catch (e) {
alert('Could not retrieve authentication token.');
throw e;
}
}
async function savePrefs() {
try {
if (!token) await getToken();
const content = JSON.stringify(prefs);
const res = await api.postWithToken('csrf', {
action: 'edit',
title: prefsPage,
summary: 'Updating preferences ([[User:DreamRimmer/PersonalEditBlocker|PersonalEditBlocker.js]])',
text: content,
format: 'json'
});
if (res.edit && res.edit.result === 'Success') {
alert('Preferences updated successfully.');
location.reload();
} else {
throw new Error('Could not save preferences.');
}
} catch (e) {
alert('Error saving preferences: ' + e.message);
}
}
class PrefsDialog extends OO.ui.ProcessDialog {
constructor(config) {
super(config);
}
static get static() {
return {
name: 'prefsDialog',
title: 'PersonalEditBlocker',
actions: [
{ action: 'save', label: 'Save', flags: ['primary', 'progressive'] },
{ action: 'cancel', label: 'Cancel', flags: ['safe', 'close'] }
]
};
}
initialize() {
super.initialize();
this.content = new OO.ui.PanelLayout({
padded: true,
expanded: false,
scrollable: false
});
this.pagesInput = new OO.ui.TextInputWidget({
placeholder: 'Enter pages, separated by commas'
});
this.enterButton = new OO.ui.ButtonWidget({
label: 'Enter',
flags: ['progressive']
});
this.enterButton.on('click', () => {
const newPages = this.pagesInput.getValue().split(',').map(w => w.trim().replace(/_/g, ' ')).filter(w => w && !prefs.protected.includes(w));
prefs.protected = prefs.protected.concat(newPages);
this.pagesInput.setValue('');
this.updateProtectedPagesList();
});
const inputWrapper = new OO.ui.Widget({
content: [this.pagesInput.$element, this.enterButton.$element],
classes: ['input-wrapper']
});
this.fieldset = new OO.ui.FieldsetLayout({ label: 'Preferences' });
this.fieldset.addItems([
new OO.ui.FieldLayout(inputWrapper, { label: 'Enter pages:', align: 'top' })
]);
this.protectedPagesList = new OO.ui.FieldsetLayout({ label: 'Protected pages:' });
this.updateProtectedPagesList();
this.content.$element.append(this.fieldset.$element);
this.content.$element.append(this.protectedPagesList.$element);
this.$body.append(this.content.$element);
}
updateProtectedPagesList() {
this.protectedPagesList.clearItems();
const items = prefs.protected.map((page) => {
const removeButton = new OO.ui.ButtonWidget({
label: 'Remove',
flags: ['destructive'],
classes: ['remove-button'],
framed: true,
title: 'Remove'
});
removeButton.$element.css({
'margin-left': '10px',
'margin-top': '2px'
});
removeButton.on('click', () => {
prefs.protected = prefs.protected.filter(p => p !== page);
this.updateProtectedPagesList();
});
return new OO.ui.FieldLayout(new OO.ui.Widget({
content: [
new OO.ui.LabelWidget({ label: `• ${page}`, classes: ['protected-page-name'] }),
removeButton
],
classes: ['protected-page-item']
}), { align: 'inline' });
});
this.protectedPagesList.addItems(items);
}
getBodyHeight() {
return 300;
}
getActionProcess(action) {
if (action === 'save') {
return new OO.ui.Process(() => {
savePrefs();
this.close();
});
} else if (action === 'cancel') {
return new OO.ui.Process(() => this.close());
}
return super.getActionProcess(action);
}
}
function showWarning() {
const div = document.createElement("div");
Object.assign(div.style, {
backgroundColor: "red",
color: "white",
padding: "10px",
textAlign: "center",
fontSize: "14px",
fontWeight: "bold",
position: "relative"
});
div.innerHTML = `Note: This page is protected. Remove it from your settings to enable editing (PersonalEditBlocker.js).`;
const btn = document.createElement("button");
Object.assign(btn.style, {
position: "absolute",
top: "2px",
right: "5px",
border: "none",
padding: "1px 3px",
cursor: "pointer",
borderRadius: "3px"
});
btn.textContent = "x";
btn.onclick = () => div.style.display = "none";
div.appendChild(btn);
$('#contentSub').before(div);
}
function preventEdit() {
const style = document.createElement('style');
style.innerHTML = `
.mw-editsection, #ca-edit, #ca-ve-edit,
a[href*="action=edit"], a[href*="veaction=edit"],
[accesskey="e"], [data-action="edit"],
.minerva-edit, .page-actions-menu__item--edit,
.mw-rollback-link, .mw-undo {
display: none !important;
}
`;
document.head.appendChild(style);
$(document).ready(() => {
$('.mw-editsection, #ca-edit, #ca-ve-edit, a[href*="action=edit"], a[href*="veaction=edit"], [accesskey="e"], [data-action="edit"], .minerva-edit, .page-actions-menu__item--edit, .mw-rollback-link, .mw-undo').remove().on('click', event => {
event.preventDefault();
alert('Editing is not allowed on this page (PersonalEditBlocker.js).');
});
mw.hook('ve.activationComplete').add(() => {
if (window.ve?.init?.target) {
ve.init.target.deactivate();
}
});
const urlParams = new URLSearchParams(window.location.search);
if (["edit", "submit", "rollback"].includes(mw.config.get("wgAction")) || urlParams.get("veaction") === "edit" || urlParams.get("action") === "rollback") {
window.location.replace(mw.util.getUrl(page));
}
});
}
async function init() {
await loadPrefs();
mw.util.addPortletLink('p-personal', '#', 'PersonalEditBlocker', 'ca-protected-pages-prefs', 'Manage protected pages preferences');
document.getElementById('ca-protected-pages-prefs').addEventListener('click', e => {
e.preventDefault();
const windowManager = new OO.ui.WindowManager();
$(document.body).append(windowManager.$element);
const prefsDialog = new PrefsDialog();
windowManager.addWindows([prefsDialog]);
windowManager.openWindow(prefsDialog);
});
if (prefs.protected.map(p => p.replace(/_/g, ' ')).includes(page)) {
showWarning();
preventEdit();
}
}
init();
});
//</nowiki>