В четверг, 7 мая, около 16 часов (MSK) регистратор заморозил домен «cyclowiki.org» без уведомления владельцев. Сайт недоступен из большинства стран. Правление изучает возможности решения проблемы.

MediaWiki:Common.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 на март 2026
 */
(function() {
    "use strict";

    // ====================== Утилиты ============================
    
    /**
     * Функция импорта скриптов
     */
    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'
            );
        });
    };

    
    // ==================== Скрипт сообщения об ошибках ============
    
    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);
        }
    })();

    // ==================== Сворачиваемые таблицы и блоки ==========
    
    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;
        }
    }

    /**
     * Сворачивание div-блоков
     */
    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);
        }
    }

    /**
     * Свернуть/развернуть div
     */
    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;
        }
    }
            
    // ==================== Инициализация сворачивания ============
    
    function initializeAll() {
        collapsibleTables();
        collapsibleDivs();
    }

    // ==================== Единая инициализация ====================
    
    /**
     * Единая точка инициализации всех скриптов
     */
    function init() {
        initializeAll();
    }
    
    // Современный способ ожидания загрузки DOM
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }

})();