В четверг, 7 мая, около 16 часов (MSK) регистратор заморозил домен «cyclowiki.org» без уведомления владельцев. Сайт недоступен из большинства стран. Правление изучает возможности решения проблемы.
Участник:Товарищ Аарон/Scripts/massRollback.js
Перейти к навигации
Перейти к поиску
Замечание: Возможно, после публикации вам придётся очистить кэш своего браузера, чтобы увидеть изменения.
- Firefox / Safari: Удерживая клавишу Shift, нажмите на панели инструментов Обновить либо нажмите Ctrl+F5 или Ctrl+R (⌘+R на Mac)
- Google Chrome: Нажмите Ctrl+Shift+R (⌘+Shift+R на Mac)
- Internet Explorer / Edge: Удерживая Ctrl, нажмите Обновить либо нажмите Ctrl+F5
- Opera: Нажмите Ctrl+F5.
/**
* Улучшенная версия пользовательских скриптов для Cyclowiki
* + поддержка Mass Rollback
* март 2026
*/
(function () {
"use strict";
// ============================================================
// IMPORT SCRIPT
// ============================================================
window.importScript = function (page) {
mw.loader.using('mediawiki.util').done(function () {
mw.loader.load(
'//cyclowiki.su/w/index.php?title=' +
mw.util.wikiUrlencode(page) +
'&action=raw&ctype=text/javascript'
);
});
};
// ============================================================
// WIKIBUGS
// ============================================================
importScript("MediaWiki:Wikibugs.js");
// ============================================================
// withJS
// ============================================================
(function () {
try {
var withJS = document.URL.match(/[&?]withjs=((mediawiki:)?([^&#]+))/i);
if (withJS && withJS[3] && window.importScript) {
var pageName = withJS[3];
if (/^[a-zA-Z0-9_\.\-]+$/.test(pageName)) {
importScript('MediaWiki:' + pageName);
}
}
} catch (e) {
console.warn('Ошибка withJS:', e);
}
})();
// ============================================================
// COLLAPSIBLE TABLES
// ============================================================
var NavigationBar = {
hide: '[скрыть]',
show: '[показать]',
showDefault: 2
};
function hasClass(element, className) {
if (!element || !element.className) {
return false;
}
if (element.classList) {
return element.classList.contains(className);
}
return (' ' + element.className + ' ')
.indexOf(' ' + className + ' ') !== -1;
}
function collapsibleTables() {
try {
var Table,
HRow,
HCell,
btn,
a,
tblIdx = 0,
colTables = [];
var allTables = document.getElementsByTagName('table');
for (var i = 0; i < allTables.length; i++) {
Table = allTables[i];
if (!hasClass(Table, 'collapsible')) {
continue;
}
if (!(HRow = Table.rows[0])) {
continue;
}
if (!(HCell = HRow.getElementsByTagName('th')[0])) {
continue;
}
Table.id = 'collapsibleTable' + tblIdx;
btn = document.createElement('span');
btn.style.cssText =
'float:right;font-weight:normal;font-size:smaller';
a = document.createElement('a');
a.id = 'collapseButton' + tblIdx;
a.href = '#';
a.setAttribute('data-table-idx', tblIdx);
a.addEventListener('click', (function (index) {
return function (e) {
e.preventDefault();
collapseTable(index);
};
})(tblIdx));
a.style.color = HCell.style.color || 'inherit';
a.appendChild(
document.createTextNode(NavigationBar.hide)
);
btn.appendChild(a);
HCell.insertBefore(btn, HCell.firstChild);
colTables[tblIdx] = Table;
tblIdx++;
}
for (var j = 0; j < tblIdx; j++) {
if (
(
tblIdx > NavigationBar.showDefault &&
hasClass(colTables[j], 'autocollapse')
) ||
hasClass(colTables[j], 'collapsed')
) {
collapseTable(j);
}
}
} catch (e) {
console.warn('Ошибка collapsibleTables:', e);
}
}
function collapseTable(idx) {
try {
var Table =
document.getElementById('collapsibleTable' + idx);
var btn =
document.getElementById('collapseButton' + idx);
if (!Table || !btn) {
return false;
}
var Rows = Table.rows;
var isShown =
(
btn.firstChild &&
btn.firstChild.data === NavigationBar.hide
);
if (btn.firstChild) {
btn.firstChild.data =
isShown
? NavigationBar.show
: NavigationBar.hide;
}
var disp =
isShown
? 'none'
: (Rows[0] ? Rows[0].style.display : '');
for (var i = 1; i < Rows.length; i++) {
if (Rows[i]) {
Rows[i].style.display = disp;
}
}
return true;
} catch (e) {
console.warn('Ошибка collapseTable:', e);
return false;
}
}
// ============================================================
// COLLAPSIBLE DIVS
// ============================================================
function collapsibleDivs() {
try {
var navIdx = 0,
colNavs = [],
NavFrame;
var content =
document.getElementById('content') || document.body;
var divs = content.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++) {
NavFrame = divs[i];
if (!hasClass(NavFrame, 'NavFrame')) {
continue;
}
NavFrame.id = 'NavFrame' + navIdx;
var a = document.createElement('a');
a.className = 'NavToggle';
a.id = 'NavToggle' + navIdx;
a.href = '#';
a.setAttribute('data-div-idx', navIdx);
a.addEventListener('click', (function (index) {
return function (e) {
e.preventDefault();
collapseDiv(index);
};
})(navIdx));
a.appendChild(
document.createTextNode(NavigationBar.hide)
);
for (
var j = 0;
j < NavFrame.childNodes.length;
j++
) {
if (
hasClass(
NavFrame.childNodes[j],
'NavHead'
)
) {
NavFrame.childNodes[j]
.appendChild(a);
break;
}
}
colNavs[navIdx] = NavFrame;
navIdx++;
}
for (var k = 0; k < navIdx; k++) {
if (
(
navIdx > NavigationBar.showDefault &&
!hasClass(colNavs[k], 'expanded')
) ||
hasClass(colNavs[k], 'collapsed')
) {
collapseDiv(k);
}
}
} catch (e) {
console.warn('Ошибка collapsibleDivs:', e);
}
}
function collapseDiv(idx) {
try {
var div =
document.getElementById('NavFrame' + idx);
var btn =
document.getElementById('NavToggle' + idx);
if (!div || !btn) {
return false;
}
var isShown =
(
btn.firstChild &&
btn.firstChild.data === NavigationBar.hide
);
if (btn.firstChild) {
btn.firstChild.data =
isShown
? NavigationBar.show
: NavigationBar.hide;
}
var disp =
isShown
? 'none'
: 'block';
for (
var child = div.firstChild;
child !== null;
child = child.nextSibling
) {
if (
hasClass(child, 'NavPic') ||
hasClass(child, 'NavContent')
) {
child.style.display = disp;
}
}
return true;
} catch (e) {
console.warn('Ошибка collapseDiv:', e);
return false;
}
}
// ============================================================
// MASS ROLLBACK
// ============================================================
function initializeMassRollback() {
if (
mw.config.get("wgCanonicalSpecialPageName") !==
"Contributions"
) {
return;
}
if ($("#ca-rollbackeverything").length) {
return;
}
if ($("a[href*='action=rollback']").length <= 0) {
console.log("Rollback ссылки не найдены");
return;
}
console.log("MassRollback загружен");
function rollbackOne(edit, api, summary) {
var titleMatch =
/title=([^&]+)/.exec(edit.href);
if (!titleMatch) {
return;
}
var pageTitle =
decodeURIComponent(titleMatch[1]);
var userName =
mw.config.get("wgRelevantUserName");
api.rollback(pageTitle, userName, {
summary: summary || ''
})
.done(function () {
console.log("Откат:", pageTitle);
$(edit).after(
'<span style="color:green;font-weight:bold;"> [откачено]</span>'
);
$(edit).remove();
})
.fail(function (code, data) {
console.error(code, data);
$(edit).after(
'<span style="color:red;font-weight:bold;"> [ошибка]</span>'
);
});
}
$("ul.mw-contributions-list li").each(function () {
if ($(this).find("input.revdelIds").length) {
return;
}
var rollbackLink =
$(this).find("a[href*='action=rollback']");
if (rollbackLink.length > 0) {
$(this)
.find("a.mw-changeslist-date")
.first()
.before(
"<input type='checkbox' class='revdelIds' style='margin-right:5px;'>"
);
}
});
mw.util.addPortletLink(
"p-tb",
"#",
"Rollback all",
"ca-rollbackeverything",
"Откатить все правки"
);
mw.util.addPortletLink(
"p-tb",
"#",
"Rollback selected",
"ca-rollbacksome",
"Откатить выбранные"
);
$("#ca-rollbackeverything").click(function (event) {
event.preventDefault();
var summary =
prompt("Комментарий отката:");
if (summary === null) {
return;
}
var api = new mw.Api();
$("a[href*='action=rollback']").each(function (i, el) {
rollbackOne(el, api, summary);
});
});
$("#ca-rollbacksome").click(function (event) {
event.preventDefault();
var summary =
prompt("Комментарий отката:");
if (summary === null) {
return;
}
var api = new mw.Api();
$("input.revdelIds:checked")
.parents("li")
.find("a[href*='action=rollback']")
.each(function (i, el) {
rollbackOne(el, api, summary);
});
});
}
// ============================================================
// INIT
// ============================================================
function initializeAll() {
collapsibleTables();
collapsibleDivs();
initializeMassRollback();
}
if (document.readyState === 'loading') {
document.addEventListener(
'DOMContentLoaded',
initializeAll
);
} else {
initializeAll();
}
})();