Ловушка запрещённого
Господа программеры, нейросеть мне набросала скрипт для уведомления о запрещённом и том, за который могут штрафовать материале. Сделан он для того, чтоб посмотреть что будет с интернетом после 1-го сентября.
Так вот будет ли этот пользовательский скрипт работать и что в нём нужно исправить?
// ==UserScript==
// @name Extremist-Filter Alert
// @namespace *
// @VERSION 1.1.1
// @Description Блокирует страницы, содержащие строки из CSV-списка экстремистских материалов.
// @match *://*/*
// @GrAnt GM_xmlhttpRequest
// @GrAnt GM.xmlHttpRequest
// @ConnecT minjust.gov.ru
// @run-at document-end
// ==/UserScript==
(() => {
const CSV_URL = 'https://minjust.gov.ru/uploaded/files/exportfsm.csv';
let csvSet = null;
loadCSV();
async function loadCSV() {
try {
// Выбираем правильный API для пользователей GM4 vs TM/VM
const xhrFunc = typeof GM_xmlhttpRequest === 'function'
? GM_xmlhttpRequest
: typeof GM !== 'undefined' && typeof GM.xmlHttpRequest === 'function'
? GM.xmlHttpRequest
: null;
if (xhrFunc) {
xhrFunc({
method: 'GET',
url: CSV_URL,
responseType: 'text',
onload: ({ responseText }) => {
csvSet = parseCSV(responseText);
scanPage();
},
onerror: err => console.error('CSV load error', err)
});
} else {
// fetch может не сработать из-за CORS, но пробуем на тех, у кого он доступен
const txt = await (await fetch(CSV_URL)).text();
csvSet = parseCSV(txt);
scanPage();
}
} catch (e) {
console.error('Ошибка загрузки CSV:', e);
}
}
// Обрезаем всё после и включая слово "решение"
function parseCSV(text) {
return new Set(
text
.split(/\r?\n/)
.map(line => {
const lower = line.toLowerCase().trim();
if (!lower) return '';
// убираем кавычки и разделители, если есть
const firstCol = lower.split(/[;,]/)[0];
const idx = firstCol.indexOf('решение');
return (idx !== -1 ? firstCol.slice(0, idx) : firstCol).trim();
})
.filter(Boolean)
);
}
function scanPage() {
if (!csvSet) return;
const bodyText = document.body.innerText
.replace(/\s+/g, ' ')
.toLowerCase();
for (const phrase of csvSet) {
if (bodyText.includes(phrase)) {
showWarning(phrase);
break;
}
}
}
function showWarning(match) {
if (document.getElementById('extremistOverlay')) return;
const css = `
#extremistOverlay {
position: fixed;
inset: 0;
background: rgba(0,0,0,0.96);
color: #fff;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 2147483647;
font: 1.15rem/1.6 system-ui, sans-serif;
}
#extremistOverlay button {
margin: 1rem;
padding: .7rem 2rem;
font-size: 1rem;
cursor: pointer;
}
#extremistOverlay h1 {
max-width: 90vw;
text-align: center;
margin-bottom: 1.2rem;
}
`;
const style = document.createElement('style');
style.textContent = css;
document.head.append(style);
const div = document.createElement('div');
div.id = 'extremistOverlay';
div.innerHTML = `
<h1>Этот материал находится в списке экстремистских материалов. Вам штраф в 5000 рублей. </h1>
<p style="opacity:.8;">Совпадение: <em>${match}</em></p>
<div>
<button id="ext-close">Убрать уведомление</button>
<button id="ext-back">Вернуться назад</button>
</div>`;
document.body.append(div);
// Пытаемся перейти в полноэкранный режим
if (div.requestFullscreen) {
div.requestFullscreen().catch(() => {});
}
document.getElementById('ext-close').onclick = () => {
if (document.exitFullscreen) document.exitFullscreen();
div.remove();
};
document.getElementById('ext-back').onclick = () => history.back();
}
})();