MediaWiki:Gadget-pagenominator.js
Замечание: Возможно, после публикации вам придётся очистить кэш своего браузера, чтобы увидеть изменения.
- Firefox / Safari: Удерживая клавишу Shift, нажмите на панели инструментов Обновить либо нажмите Ctrl+F5 или Ctrl+R (⌘+R на Mac)
- Google Chrome: Нажмите Ctrl+Shift+R (⌘+Shift+R на Mac)
- Edge: Удерживая Ctrl, нажмите Обновить либо нажмите Ctrl+F5
- Opera: Нажмите Ctrl+F5.
// На основе https://ru.wikipedia.org/w/index.php?title=Участник:Higimo/remove.js
// Оставлено создание номинаций КУ, много КУ, КБУ. Остальные отключены, хотя остались в коде.
var namespace = mw.config.get('wgNamespaceNumber');
if (namespace !== -1) {
$(document).ready(function() {
/*
Инициализация итератора
*/
var i = 0,
/*
Инициализация переменной устанавливающей флаг на чекбоксе,
который влияет на выполнение функции оповещающей создателя статьи
*/
g_user_alert = 0, // указать, чтоб не уведомлять пользователя
setAlert = (typeof g_user_alert === 'undefined') ? 1 : g_user_alert,
// Переключатель открытия номинаций (новых тем) на ВТ:КУ
createNomination = true,
/*
Список всех доступных причин КБУ
Коды для админов, текст для остальных.
Используется максимально короткий шаблон.
Третий параметр — условие для появления <input>
*/
fastRemove = [
['d|', 'Причина не указана' ],
['d|О1 Бессвязная статья', 'О1 Бессвязная статья' ],
['d|О2 Тестовая статья', 'О2 Тестовая статья' ],
['d|О3 Вандальная статья', 'О3 Вандальная статья' ],
['d|О4 Повторное создание', 'О4 Повторное создание' ],
['d|О5 Автор запросил удаление','О5 Автор запросил удаление' ],
['d|О6 СО или подстраница', 'О6 СО или подстраница' ],
['d|О7 Для переименования', 'О7 Для переименования', 'страницу'],
['d|О8 Дубликат статьи', 'О8 Дубликат статьи', 'страницу'],
['d|О9 Реклама или спам', 'О9 Реклама или спам' ],
['d|О10 Нецелев. использ. СО', 'О10 Нецелев. использ. СО' ],
['d|О11 Нарушены АП', 'О11 Нарушены АП', 'ссылку'],
['d|С1 Пусто или коротко', 'С1 Пусто или коротко' ],
['d|С2 Надмозг', 'С2 Надмозг' ],
['d|С3 Лишь ссылки', 'С3 Лишь ссылки' ],
['d|С5 Значимости нет', 'С5 Значимости нет' ],
['d|П1 Перенаправл. в никуда', 'П1 Перенаправл. в никуда' ],
['d|П2 Межпростр. перенаправ.', 'П2 Межпростр. перенаправ.' ],
['d|П3 Ошибочное перенап.', 'П3 Ошибочное перенап.' ],
['d|П4 Не прав. падеж', 'П4 Не прав. падеж' ],
['d|П5 Бессмысленное перенаправ.', 'П5 Бессмысленное перенаправ.' ],
['П6 Перенаправление на СО', 'П6 Перенаправление на СО' ],
['Ф1 Копия файла', 'Ф1 Копия файла', 'файл'],
['Ф2 Повреждённый файл', 'Ф2 Повреждённый файл' ],
['Ф3 Нет данных о лицензии', 'Ф3 Нет данных о лицензии' ],
['Ф3 Нет данных о источнике', 'Ф3 Нет данных о источнике' ],
['Ф3 Нет данных о авторе', 'Ф3 Нет данных о авторе' ],
['Ф3 Сомнительные данные файла','Ф3 Сомнительные данные файла' ],
['Ф4 Неиспользуемый КДИ', 'Ф4 Неиспользуемый КДИ' ],
['Ф5 Нет КДИ', 'Ф5 Нет КДИ' ],
['Ф6 Неоправданное КДИ', 'Ф6 Неоправданное КДИ' ],
['Ф8 Есть на Складе', 'Ф8 Есть на Складе', 'файл'],
['Ф9 Файл — ВП:НЕХОСТИНГ', 'Ф9 Файл — ВП:НЕХОСТИНГ' ],
['К1 Пустая категория', 'К1 Пустая категория' ],
['К2 Переимен. кат.', 'К2 Переимен. кат.', 'категорию'],
['У1 По запросу владельца', 'У1 По запросу владельца' ],
['У2 Обсуждение анонима', 'У2 Обсуждение анонима' ],
['У3 Несуществующий участник', 'У3 Несуществующий участник' ],
['У4 Нецелевое использование', 'У4 Нецелевое использование' ],
['У5 Подстраница инактива', 'У5 Подстраница инактива' ]
],
/*
Генератор кода для меню на каждой странице
*/
// menu = 'imp=КУЛ|rnm=КПМ|tRm=КУ|mRm=МНОГО КУ|ret=Оставить|noRnm=Не переименовано|fRm=КБУ|merge=КОБ|recov=ВУС|split=Разделить|'.replace(/(.*?)=(.*?)\|/g, '<li><a id=$1>$2</a></li>'),
menu = 'tRm=КУ|mRm=МНОГО КУ|fRm=КБУ|'.replace(/(.*?)=(.*?)\|/g, '<li><a id=$1>$2</a></li>'),
/*
Селектор для темы Вектор, чтобы добавлять собственное выпадающее меню
*/
vector = $('#p-views'),
/*
Функция запроса к API.
Запрос бывает двух видов: edit и parse.
Чтоб каждый раз не передавать параметр, он — булева переменная
Токен и формат каждый раз дополняется перед запросом.
Токен и формат обязателен.
Аргументы:
1. Передаваемые параметры
2. Используемый режим
3. Колбек
void apiReq(object, bool, function(result, status))
*/
apiReq = function(param, mode, callback) {
param.format = 'json';
param.token = mw.user.tokens.get('csrfToken');
param.action =
mode === 0 ? 'edit' :
mode === 1 ? 'parse' : 'query';
$.post('/w/api.php', param, callback);
},
/*
Функция получения даты.
Необходимо, например, для КУ-запросов.
Есть возможность указать собственную дату для подытоживания номинации.
['1051-32-33', '20 апреля 2014'] getDate(string)
*/
getDate = function(s) {
var d = (!!s) ? new Date(s) : new Date();
return [d.toISOString().substr(0, 10), d.getUTCDate() + ' ' +
'января,февраля,марта,апреля,мая,июня,июля,августа,сентября,октября,ноября,декабря'.split(',')[d.getUTCMonth()] +
' ' + d.getUTCFullYear()];
},
/*
Функция получения <input>
* Атрибут «h» используется в КБУ, указывая type
* Атрибут placeholder используется везде, для улучшения UI
* Атрибут id используется везде для получения информации из поля
string getInput(string, string, bool)
*/
getInput = function(id, p, h) {
return '<input id=' + id + ' type=' + (h ? 'hidden' : 'text') + ' placeholder="' + p + '" class=messagebox>';
},
/*
Функция получения текстов статьи и её СО
getTexts(string, string, function(string, string))
*/
getTexts = function(pg, pgtl, clbck) {
getText = {prop: 'wikitext'};
getText.page = pg;
apiReq(getText, 1, function(txt1) {
getText.page = pgtl;
apiReq(getText, 1, function(txt2) {
clbck(
txt1.parse ? txt1.parse.wikitext['*'] : '',
txt2.parse ? txt2.parse.wikitext['*'] : ''
);
});
});
},
/*
Функция отправки уведомления пользователю
По выполнению вызывает callback
userAlert(object, string, string, function())
*/
userAlert = function(param, pg, msg, clbck) {
apiReq({
prop: 'revisions',
rvprop: 'user',
rvdir: 'newer',
titles: pg
}, 2, function (t) {
i = t.query.pages;
name = (typeof i['-1'] === 'undefined') ? i[Object.keys(i)[0]].revisions[0].user : '';
if (!/(\d{1,3}\.){3}\d/.test(name) && setAlert) {
apiReq({
title: 'оу:' + name,
section: 'new',
sectiontitle: param.sum,
summary: param.sum,
text: '~~\~~'
}, 0, function() {
clbck();
});
} else {
clbck();
}
});
},
/*
Функция работы с текстом статьи.
Получает адрес страницы обсуждения, получает тексты, определяет
необходимые шаблоны и устанавливает их на СО или статью.
changeArticle(object, string, string, function(string))
*/
changeArticle = function(param, pg, date, clbck) {
var so = mw.config.get('wgFormattedNamespaces')[namespace + 1] + ':' + pg.replace(/.*?:/, ''),
fiRm = function(s) { // строка в викиссылку
s = s.replace(/^[\s\[]+|[\s\]]+$/g, ''); // trim
return s.length > 0 ? '[['+s+']]' : ''; // обёртка в '[[]]'
};
getTexts(pg, so, function(article, talk) {
// Дописать остальные итоговые кнопочки и просто добавить. еще и привести в норм. состояние.
var tpl;
if (/(noRnm)/g.test(param[0])) { //не переименовано
tpl = RegExp('(' + param[3].join('|') + ')\\|(\\d{4}-\\d\\d-\\d\\d)\\|?(.*?)}', 'gi').exec(article);
if (tpl === null)
location.reload();
date = getDate(tpl[2]);
apiReq({
summary: param.sum.replace(/(\[В.*)\/.*?#/g, '$1/' + date[1] + '#'),
title: so,
text: '{\{' + param[4] + '|' + date[1] + '|' + pg + '|' + tpl[3] + '}}\n' + talk
}, 0);
article = article.replace(RegExp('(<noin.*?>)?{\{(' + param[3].join('|') + ').*?}}?(<\/noin.*?>)?', 'gi'), '');
}
if (/(ret)/g.test(param[0])) {//оставлено
tpl = RegExp('(' + param[3].join('|') + ')\\|(\\d{4}-\\d\\d-\\d\\d)\\|?(.*?)}', 'gi').exec(article);
if (tpl === null)
location.reload();
date = getDate(tpl[2]);
apiReq({
summary: param.sum.replace(/(\[В.*)\/.*?#/g, '$1/' + date[1] + '#'),
title: so,
text: '{\{' + param[4] + '|' + date[1] + '|' + tpl[3] + '}}\n' + talk
}, 0);
article = article.replace(RegExp('(<noin.*?>)?{\{(' + param[3].join('|') + ').*?}}?(<\/noin.*?>)?', 'gi'), '');
}
tpl = '<noinclude>{\{' +
(
param[0] == 'imp'
? 'подст:КУЛ'
: /(tRm|mRm)/g.test(param[0])
? 'К удалению|date=' + date[0]
: param[0] == 'fRm'
? fastRemove[$('#rmSel').val()][0] + ' ' + fiRm($('#fiRm').val())
: param[0] == 'rnm'
? 'Кпм|' + date[0] + '|' + $('#rmHeader').val() + '|' + param.rmnNom
: param[0] == 'merge'
? 'subst:слить|' + $('#rmHeader').val()
: param[0] == 'split'
? 'split|' + date[0] + '|' + '[[' + $('#rmHeader').val() + ']] и [[' + $('#rmHeader2').val() + ']]'
: ''
) + '}}</noinclude>';
apiReq({
title: pg,
text: (tpl.length > 30 ? tpl : '') + article,
summary: param.sum
}, 0, function() {
clbck(pg);
});
});
},
/*
Функция установки номинации на соответствующую страницу
Аргументы:
1. Параметры
2. Заголовок номинации
3. Текст размещаемого сообщения
4. Колбек
void setNominate(param, section, msg, callback)
*/
setNominate = function(param, section, msg, callback) {
if (/(imp|rnm|tRm|mRm|merge|recov|split)/g.test(param[0])) {
apiReq({
title: param.place,
section: 'new',
sectiontitle:
'mRm' == param[0]
? section
: /(rnm|split|merge)/g.test(param[0])
? '[[:' + param.rmnNom.replace(/( → |, )/g, ']]$1[[:') + ']]'
: '[[:' + section + ']]',
summary: param.sum,
text: msg
}, 0, function() {
callback();
});
} else {
callback();
}
},
/*
Функция создания и обработки модального окна
void modalHandler(array)
*/
modalHandler = function(param) {
var content = '';
if (param[0] == 'mRm') {
content += getInput('rmHeader', 'Заголовок номинации');
for (i = 0; i < 5; i++) {
content += getInput('rmArticle' + i, 'Статья' + (i + 1));
}
}
if (param[0] == 'fRm') {
content += '<select id=rmSel class=messagebox>';
for (i = 0; i < fastRemove.length; i++) {
content += '<option value=' + i + '>' + fastRemove[i][1] + '</option>';
}
content += '</select>' + getInput('fiRm', '', 1);
}
if (param[0] == 'rnm') {
content += getInput('rmHeader', 'Новое название');
}
if (param[0] == 'merge') {
content += getInput('rmHeader', 'Объединить с…');
}
if (param[0] == 'split') {
content += getInput('rmHeader', 'Разделить на эту');
content += getInput('rmHeader2', 'И на эту');
}
if (/(imp|tRm|mRm|rnm|merge|recov|split)/g.test(param[0])) {
content += '<textarea id=rmMsg placeholder="Текст номинации без «~~\~~»." rows=4></textarea>';
}
$('#content').prepend(
'<div id=rmWindow style="padding:2em;margin:1em;border:1px solid #985; background: #fec;">' +
'<h1>' + param[1] + '</h1>' +
content + '<br>' +
'<label><input name="rmUAlert" type=checkbox ' + ((setAlert) ? 'checked' : '') + '>Оповещать пользователя</label><br>' +
(param[0] == 'fRm' ? '' : '<label><input name="rmCreateNomination" type=checkbox ' + (createNomination ? 'checked' : '') + '>Открывать номинацию на ВТ:КУ</label><br>') +
'<div style="margin-top:1em;margin-right:1em;" ><button id=rmBtn class=mw-ui-button>Отправить</button><button id=rmClose class=mw-ui-button>Отмена</button><div>'
);
// дополнительное поле ("укажите страницу" и т.п.)
$('#rmSel').change(function() {
i = fastRemove[this.value][2];
$('#fiRm').attr({type: (i ? 'text' : 'hidden'), placeholder: 'Укажите ' + i});
});
$('#rmClose').click(function() {
$('#rmWindow').remove();
});
$('#rmBtn').click(function() {
setAlert = $('[name="rmUAlert"]').is(':checked');
createNomination = $('[name="rmCreateNomination"]').is(':checked');
$('#rmWindow')
.append('<b class=mw-small-spinner></b>')
.children().attr('disabled', '1');
var date = getDate(),
msg = $('#rmMsg').val(),
wind = $('#rmWindow'),
pg = mw.config.get('wgPageName').replace(/_/g, ' '),
ttl = $('#rmHeader').val(),
ttl2 = $('#rmHeader2').length ? $('#rmHeader2').val() : '';
param.place = param[2] ? 'Викитека:' + param[2] : '';
param.rmnNom = pg + ' → ' + ttl + (ttl2.length ? ', ' + $('#rmHeader2').val() : '');
if (createNomination) {
param.sum = 'Удалятор: [[' + (param.place ? param.place + '#' : '') + pg + ']] — ' + param[1];
} else {
param.sum = 'Удалятор: ' + param[1];
}
i = 0;
if ($('#rmArticle0')[0]) {
i = 4;
msg = '=== По всем ===\n' + msg;
}
if (/(rnm|split|merge)/g.test(param[0])) {
param.sum = param.sum.replace(/#.*]]/g, '#' + param.rmnNom + ']]');
}
for (; i >= 0; i--) {
if ($('#rmArticle0')[0])
pg = $('#rmArticle' + i).val();
if (pg.length) {
if ($('#rmArticle0')[0]) {
param.sum = param.sum.replace(/#.*?\]/g, '#' + (ttl ? ttl : pg) + ']');
msg = '=== [[:' + pg + ']] ===\n' + msg;
}
changeArticle(param, pg, date, function(pg) {
wind.append('Исправлена статья «' + pg + '»<br>');
userAlert(param, pg, msg + ' ~~\~~', function() {
if (setAlert) wind.append('Уведомлен создатель<br>');
setNominate(param, (ttl ? ttl : pg), msg + ' --~~\~~', function() {
if (createNomination) {
wind.append('Номинация записана<br>');
if (/(imp|rnm|tRm|mRm|recov|merge)/g.test(param[0])) {
wind.append('Открытие номинации<br>');
window.open('/wiki/' + param.place + '#' + encodeURI(pg.replace(/ /g, '_')).replace(/%/g, '.'));
}
location.reload();
}
})
})
})
}
}
});
/*
Реализация ctrl+enter события
*/
$(window).keydown(function (e) {
if (e.ctrlKey && e.keyCode === 13)
$('#rmBtn').click();
});
};
/*
Добавление выпадающего меню на все страницы
*/
if (/\.([0-7]|1([0-1]([01])?|[45])?)\./g.test('.' + namespace + '.')) {
if (mw.config.get('skin') == 'vector')
$('#p-views').after('<nav class="mw-portlet vector-menu vector-menu-dropdown vector-menu-dropdown-noicon" id="p-remove-js"><input class="vector-menu-checkbox" type="checkbox" aria-labelledby="p-remove-js-label"><h3 id="p-remove-js-label" class="vector-menu-heading"><span>Удалятор</span></h3><div class="vector-menu-content"><ul class="vector-menu-content-list">' + menu + '</ul></div></nav>');
else
$('#ca-history').after(menu);
}
/*
Событие по клику на любую кнопку выпадающего меню
*/
$('#imp,#tRm,#mRm,#ret,#fRm,#noRnm,#rnm,#merge,#recov,#split').click(function() {
i = this.id;
modalHandler(
// [текущее действие, название модального окна и комментарий, название страницы, поддерживаемые шаблоны
i == 'imp' ? [ i, 'Номинация КУЛ', 'К улучшению' ] :
i == 'rnm' ? [ i, 'Номинация КПМ', 'К переименованию' ] :
i == 'tRm' ? [ i, 'Номинация КУ', 'К удалению' ] :
i == 'mRm' ? [ i, 'Номинация МНОГО КУ', 'К удалению' ] :
i == 'ret' ? [ i, 'Оставлено', 'К удалению', ['ку', 'к удалению'], 'Оставлено' ] :
i == 'noRnm'? [ i, 'Не переименовано', 'К переименованию', ['кпм', 'к переименованию'],'Не переименовано' ] :
i == 'merge'? [ i, 'Номинация КОБ', 'К объединению' ] :
i == 'recov'? [ i, 'Номинация ВУС', 'К восстановлению' ] :
i == 'split'? [ i, 'Номинация к разделению','К разделению' ] :
i == 'fRm' ? [ i, 'Номинация КБУ' ] : 0
);
});
});
}