MediaWiki:Gadget-april-fools.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.
/**
* Первоапрельский гаджет
* Заменяет содержимое заглавной страницы на объявление
*/
( function () {
'use strict';
// Проверяем, что это заглавная страница
var title = mw.config.get( 'wgTitle' );
var isMainPage = ( title === 'Заглавная страница' || title === 'Main_Page' );
// Проверяем дату
var today = new Date();
var isAprilFools = ( today.getMonth() === 3 && today.getDate() === 1 );
// Проверяем, не отключен ли гаджет через URL (?april=off)
var urlParams = new URLSearchParams( window.location.search );
var isDisabled = ( urlParams.get( 'april' ) === 'off' );
// Если не подходит — выходим
if ( !isMainPage || !isAprilFools || isDisabled ) {
return;
}
// Добавляем класс на body для активации стилей
document.body.classList.add( 'april-fools-active' );
// Ключ для localStorage (чтобы запомнить оторванный корешок)
var STORAGE_KEY = 'april_fools_ticket_ripped';
var isTicketRipped = localStorage.getItem( STORAGE_KEY ) === 'true';
// Функция создания HTML структуры
function buildAprilFoolsHTML() {
return `
<div class="april-notice">
<div class="tape-corner top-left"></div>
<div class="tape-corner top-right"></div>
<div class="tape-corner bottom-left"></div>
<div class="tape-corner bottom-right"></div>
<div class="april-header">
<span>⚠️ В Н И М А Н И Е ⚠️</span>
</div>
<div class="april-content">
<h2>Absurdopedia.wiki</h2>
<div class="subhead">энциклопедия, которую мы потеряли</div>
<p><strong>ВРЕМЕННО НАХОДИТСЯ</strong></p>
<div class="april-address" data-action="address">
🏠 ул. Логическая, д. 0, кв. ∞
</div>
<div class="address-hint" style="font-size: 0.7rem; color: #9b8a60; margin-top: -0.5rem;">
(домофон не работает. кричите «абсурд» — откроют)
</div>
<div class="april-reason">
<strong>📋 Причина:</strong> плановая замена смыслов.<br>
Работы проводятся с 00:00 до <strong>никогда</strong>.<br>
Приносим извинения за неудобства, <span style="text-decoration: line-through;">которых</span> не существует.
</div>
<div class="april-support" data-action="support">
<strong>📞 Техподдержка:</strong><br>
позвоните по номеру, который вы сейчас придумали в голове.
<div class="support-hint">
(если не придумали — значит, всё в порядке)
</div>
</div>
<div class="april-ticket" id="april-ticket-container">
${isTicketRipped ?
'<div class="ticket-ripped-message"><s>корешок оторван</s><br>✨ вы свободны. или нет. проверьте карманы ✨</div>' :
'<button class="ticket-button" data-action="ticket">[ ОТОРВАТЬ КОРЕШОК ]</button>'
}
<div class="ticket-note" style="font-size: 0.65rem; margin-top: 0.8rem; color: #9b8a60;">
*корешок существует только в вашем воображении.<br>
но это не освобождает вас от ответственности
</div>
</div>
</div>
<div class="april-footer">
<p>📌 Объявление расклеено:<br>
• на всех подъездах вашего разума<br>
• в лифте вашего внимания<br>
• на холодильнике вашей совести</p>
<p class="small">*если вы читаете это объявление второй раз — ничего страшного, это нормальная петля времени<br>
*если вы читаете это объявление третий раз — вы нам нравитесь. оставайтесь. мы вас запомнили</p>
<p class="small" style="margin-top: 0.8rem;">🔍 вернуться к обычной версии: <a href="?april=off" style="color: #8b5a2b;">?april=off</a></p>
</div>
</div>
`;
}
// Функция создания модального окна
function showModal( content, buttonText, callback ) {
// Удаляем существующее модальное окно, если есть
var existingModal = document.getElementById( 'april-modal' );
if ( existingModal ) {
existingModal.remove();
}
var modal = document.createElement( 'div' );
modal.id = 'april-modal';
modal.className = 'april-modal';
modal.innerHTML = `
<div class="april-modal-content">
${content}
<button class="april-modal-close">${buttonText || 'Закрыть'}</button>
</div>
`;
document.body.appendChild( modal );
modal.style.display = 'flex';
var closeBtn = modal.querySelector( '.april-modal-close' );
closeBtn.addEventListener( 'click', function () {
modal.style.display = 'none';
modal.remove();
if ( callback ) callback();
} );
// Закрытие по клику вне окна
modal.addEventListener( 'click', function ( e ) {
if ( e.target === modal ) {
modal.style.display = 'none';
modal.remove();
if ( callback ) callback();
}
} );
}
// Обработка отрывания корешка
function handleTicketRip( button ) {
if ( isTicketRipped ) return;
isTicketRipped = true;
localStorage.setItem( STORAGE_KEY, 'true' );
// Заменяем кнопку на сообщение
var container = document.getElementById( 'april-ticket-container' );
if ( container ) {
container.innerHTML = `
<div class="ticket-ripped-message">
<s>корешок оторван</s><br>
✨ вы свободны. или нет. проверьте карманы ✨
</div>
<div class="ticket-note" style="font-size: 0.65rem; margin-top: 0.8rem; color: #9b8a60;">
*корешок существует только в вашем воображении.<br>
но это не освобождает вас от ответственности
</div>
`;
}
// Показываем модальное окно
showModal(
'<p><strong>📄 КОРЕШОК ОТОРВАН</strong></p>' +
'<p>Вы совершили необратимое действие.<br>' +
'Корешок у вас. Что с ним делать — мы не знаем. Это ваша проблема теперь.</p>' +
'<p>В соответствии с пунктом 0 статьи ∞ правил внутреннего распорядка,<br>' +
'вы обязаны:</p>' +
'<p>• написать статью про то, <strong>почему вы это сделали</strong><br>' +
'• срок — до конца жизни<br>' +
'• объём — от одного слова до бесконечности</p>' +
'<p style="font-size: 0.8rem; color: #8b7a5a;">(подсказка: можно начать с фразы «потому что...»)</p>',
'Я понял, что наделал'
);
}
// Обработка клика по адресу
function handleAddressClick() {
if ( typeof console !== 'undefined' ) {
console.log( '%c📍 вы ищете то, что не ищется. достойно уважения', 'color: #b89a40; font-size: 12px;' );
}
showModal(
'<p><strong>🏠 ул. Логическая, д. 0, кв. ∞</strong></p>' +
'<p>На картах этого адреса нет.<br>' +
'Но вы всё равно попробуйте найти.<br>' +
'Мы будем следить.</p>' +
'<p style="font-size: 0.8rem;">🗺️ подсказка: идите туда, где заканчиваются мысли</p>',
'Понял, продолжу поиски'
);
}
// Обработка клика по техподдержке
function handleSupportClick() {
showModal(
'<p><strong>📞 ЗВОНОК ТЕХПОДДЕРЖКЕ</strong></p>' +
'<p>Вы набрали номер... какой вы набрали?<br>' +
'Ах да, тот самый.</p>' +
'<p>— Алло?<br>' +
'— ...<br>' +
'— Мы не работаем сегодня.<br>' +
'И вчера не работали. И завтра не будем.<br>' +
'Но спасибо, что спросили.</p>' +
'<p>— ...<br>' +
'— Да, с праздником.</p>' +
'<p><em>*гудки*</em></p>',
'ПОЛОЖИТЬ ТРУБКУ'
);
}
// Основная функция
function init() {
// Находим контейнер с содержимым
var contentDiv = document.getElementById( 'mw-content-text' );
if ( !contentDiv ) {
// Пробуем альтернативные селекторы для разных скинов
contentDiv = document.querySelector( '#content #mw-content-text' ) ||
document.querySelector( '.mw-body-content' );
}
if ( contentDiv ) {
// Сохраняем оригинальное содержимое (на случай, если понадобится)
contentDiv.setAttribute( 'data-april-original', 'true' );
contentDiv.innerHTML = buildAprilFoolsHTML();
// Навешиваем обработчики событий
var ticketBtn = document.querySelector( '[data-action="ticket"]' );
if ( ticketBtn ) {
ticketBtn.addEventListener( 'click', function () {
handleTicketRip( ticketBtn );
} );
}
var addressEl = document.querySelector( '[data-action="address"]' );
if ( addressEl ) {
addressEl.addEventListener( 'click', handleAddressClick );
}
var supportEl = document.querySelector( '[data-action="support"]' );
if ( supportEl ) {
supportEl.addEventListener( 'click', handleSupportClick );
}
}
// Консольное сообщение при открытии DevTools (детекция)
var devtools = /Chrome|Firefox/.test( navigator.userAgent );
if ( devtools ) {
setTimeout( function () {
console.log( '%c================================================\n🕵️♂️ А вы любопытный.\n\nЕсли вы ищете, где спрятаны статьи —\nони там же, где были всегда.\n\nА если вы ищете смысл —\nон под ковриком. нет, не тем. тем, который\nлежит в квартире вашей бабушки.\n\nС Первым апреля.\n================================================', 'color: #b89a40; font-size: 12px;' );
}, 1000 );
}
// Защита копирования с умным сообщением
document.addEventListener( 'copy', function ( e ) {
var selection = window.getSelection().toString();
if ( selection && selection.length > 0 && document.querySelector( '.april-notice' ) ) {
e.preventDefault();
e.clipboardData.setData( 'text/plain', '📋 вы скопировали объявление. теперь оно существует в двух местах. это удваивает вашу ответственность. не благодарите.\n\n(оригинал всё ещё на ул. Логической, д. 0)' );
}
} );
}
// Ждём загрузки DOM
if ( document.readyState === 'loading' ) {
document.addEventListener( 'DOMContentLoaded', init );
} else {
init();
}
} )();