MediaWiki:Common.js: различия между версиями

Страница интерфейса MediaWiki
Нет описания правки
Нет описания правки
Строка 1: Строка 1:
$(document).ready(function() {
(function() {
     // Инициализация боковой панели
    'use strict';
     $('.боковая-панель-кнопка').on('click', function() {
   
         var targetId = $(this).data('target');
     // Глобальный менеджер для Tippy.js
     window.MediaWikiTooltips = {
        loaded: false,
         callbacks: [],
          
          
         // Удаляем активный класс у всех кнопок
         load: function(callback) {
        $('.боковая-панель-кнопка').removeClass('active');
            if (this.loaded && window.tippy) {
        // Добавляем активный класс текущей кнопке
                callback();
        $(this).addClass('active');
                return;
          
            }
        // Скрываем все разделы
           
         $('.боковая-панель-раздел').removeClass('default');
            this.callbacks.push(callback);
        // Показываем выбранный раздел
           
        $('#' + targetId).addClass('default');
            if (this.loading) return;
     });
            this.loading = true;
           
            var self = this;
            var popperScript = document.createElement('script');
            popperScript.src = 'https://unpkg.com/@popperjs/core@2/dist/umd/popper.min.js';
            popperScript.onload = function() {
                var tippyScript = document.createElement('script');
                tippyScript.src = 'https://unpkg.com/tippy.js@6/dist/tippy-bundle.umd.min.js';
                tippyScript.onload = function() {
                    self.loaded = true;
                    self.loading = false;
                    self.callbacks.forEach(function(cb) { cb(); });
                    self.callbacks = [];
                };
                document.head.appendChild(tippyScript);
            };
            document.head.appendChild(popperScript);
           
            var tippyCSS = document.createElement('link');
            tippyCSS.rel = 'stylesheet';
            tippyCSS.href = 'https://unpkg.com/tippy.js@6/dist/tippy.css';
            document.head.appendChild(tippyCSS);
         }
    };
   
    // Модуль боковой панели
    var SidebarModule = {
         init: function() {
            var buttons = document.querySelectorAll('.боковая-панель-кнопка');
            var sections = document.querySelectorAll('.боковая-панель-раздел');
           
            if (buttons.length === 0) return;
           
            buttons.forEach(function(button) {
                button.addEventListener('click', function() {
                    var targetId = this.dataset.target;
                   
                    buttons.forEach(function(btn) { btn.classList.remove('active'); });
                    this.classList.add('active');
                   
                    sections.forEach(function(section) { section.classList.remove('default'); });
                    var targetSection = document.getElementById(targetId);
                    if (targetSection) {
                        targetSection.classList.add('default');
                    }
                });
            });
           
            buttons[0].click();
        }
     };
      
      
     // Активируем первую кнопку по умолчанию
     // Модуль подсказок допусков
     $('.боковая-панель-кнопка:first').click();
     var AccessTooltipsModule = {
        init: function() {
            var containers = document.querySelectorAll('.допуск-контейнер');
            if (containers.length === 0) return;
           
            MediaWikiTooltips.load(function() {
                containers.forEach(function(container) {
                    var contentElement = container.querySelector('.допуск-подсказка');
                    if (!contentElement) return;
                   
                    var content = contentElement.innerHTML;
                    tippy(container, {
                        content: content,
                        allowHTML: true,
                        interactive: true,
                        placement: 'auto',
                        maxWidth: 500,
                        theme: 'dark',
                        arrow: true,
                        duration: [200, 200],
                        popperOptions: {
                            modifiers: [
                                {
                                    name: 'preventOverflow',
                                    options: { padding: 8 }
                                },
                                {
                                    name: 'flip',
                                    options: {
                                        fallbackPlacements: ['top', 'bottom', 'right', 'left']
                                    }
                                }
                            ]
                        }
                    });
                });
            });
        }
    };
      
      
     // Подключаем Tippy.js через CDN динамически
     // Модуль подсказок законов
     if (!window.tippy) {
     var LawTooltipsModule = {
        var tippyScript = document.createElement('script');
        init: function() {
        tippyScript.src = "https://unpkg.com/@popperjs/core@2/dist/umd/popper.min.js";
            var tableCells = document.querySelectorAll('.law-tooltips td, .law-tooltips th');
         tippyScript.onload = function() {
            if (tableCells.length === 0) return;
             var tippyCoreScript = document.createElement('script');
           
             tippyCoreScript.src = "https://unpkg.com/tippy.js@6/dist/tippy-bundle.umd.min.js";
            MediaWikiTooltips.load(function() {
            tippyCoreScript.onload = initTippy;
                var lawData = LawTooltipsModule.extractLawData();
            document.head.appendChild(tippyCoreScript);
                LawTooltipsModule.initCellTooltips(tableCells, lawData);
        };
            });
        document.head.appendChild(tippyScript);
         },
 
       
        // Подключаем CSS
        extractLawData: function() {
        var tippyCSS = document.createElement('link');
             var lawData = {};
         tippyCSS.rel = "stylesheet";
            var detailTables = document.querySelectorAll('.mw-collapsible-content table');
        tippyCSS.href = "https://unpkg.com/tippy.js@6/dist/tippy.css";
              
        document.head.appendChild(tippyCSS);
            detailTables.forEach(function(table) {
    } else {
                var rows = table.querySelectorAll('tr');
        initTippy();
               
    }
                rows.forEach(function(row) {
 
                    var cells = row.querySelectorAll('td');
    // Инициализация Tippy после загрузки скриптов
                    if (cells.length < 3) return;
    function initTippy() {
                   
        $('.допуск-контейнер').each(function() {
                    var crimeCell = cells[0];
            var content = $(this).find('.допуск-подсказка').html(); // берем содержимое подсказки
                    var descriptionCell = cells[1];
            tippy(this, {
                    var exampleCell = cells[2];
                content: content,
                   
                allowHTML: true,
                    var anchor = crimeCell.querySelector('[id]');
                interactive: true,
                    if (!anchor) return;
                placement: 'auto',     // автоматический выбор позиции
                   
                maxWidth: '500px',
                    var lawCode = anchor.id;
                minHeight: 'auto',
                    var titleElement = crimeCell.querySelector('b');
                theme: 'dark',         // темная тема
                   
                arrow: true,           // без стрелки
                    if (titleElement && lawCode.match(/^\d{3}$/)) {
                duration: [200, 200],   // плавное появление/исчезание
                        var titleText = titleElement.textContent.trim();
                popperOptions: {
                        var lawTitle = titleText.replace(/^\d{3}\s*/, '').replace(/^\d{3}/, '').trim();
                    modifiers: [
                        var description = descriptionCell.textContent.trim();
                        {
                       
                            name: 'preventOverflow',
                        var examples = [];
                             options: {
                        var exampleItems = exampleCell.querySelectorAll('li');
                                 padding: 8 // отступ от краев экрана
                        exampleItems.forEach(function(item) {
                            var text = item.textContent.trim();
                            if (text) examples.push(text);
                        });
                       
                        lawData[lawCode] = {
                            title: lawTitle,
                            description: description,
                            examples: examples
                        };
                    }
                });
            });
           
            return lawData;
        },
       
         createTooltipContent: function(lawCode, lawData) {
            var data = lawData[lawCode];
            if (!data) return null;
           
            var html = '<div class="law-tooltip">';
            html += '<h4 class="law-tooltip-title">' + lawCode + ' - ' + data.title + '</h4>';
            html += '<p class="law-tooltip-description">' + data.description + '</p>';
           
            if (data.examples && data.examples.length > 0) {
                html += '<div class="law-tooltip-examples">';
                html += '<strong>Примеры:</strong><ul>';
                data.examples.slice(0, 5).forEach(function(example) {
                    html += '<li>' + example + '</li>';
                });
                html += '</ul></div>';
            }
            html += '</div>';
           
            return html;
        },
       
        initCellTooltips: function(tableCells, lawData) {
            tableCells.forEach(function(cell) {
                var link = cell.querySelector('a[href*="#"]');
                if (!link) return;
               
                var href = link.getAttribute('href');
                var match = href.match(/#(\d{3})/);
                if (!match) return;
               
                var lawCode = match[1];
                var tooltipContent = LawTooltipsModule.createTooltipContent(lawCode, lawData);
                if (!tooltipContent) return;
               
                cell.classList.add('law-cell-with-tooltip');
               
                cell.addEventListener('click', function(e) {
                    e.preventDefault();
                    window.location.hash = lawCode;
                });
               
                tippy(cell, {
                    content: tooltipContent,
                    allowHTML: true,
                    interactive: true,
                    placement: 'top',
                    maxWidth: 400,
                    theme: 'law-theme',
                    arrow: true,
                    duration: [200, 150],
                    delay: [0, 50],
                    appendTo: document.body,
                    boundary: 'viewport',
                    popperOptions: {
                        strategy: 'fixed',
                        modifiers: [
                            {
                                name: 'preventOverflow',
                                options: {
                                    boundary: 'viewport',
                                    padding: 20,
                                    altAxis: true,
                                    altBoundary: true
                                }
                            },
                             {
                                name: 'flip',
                                options: {
                                    fallbackPlacements: ['bottom', 'left', 'right']
                                }
                            },
                            {
                                name: 'computeStyles',
                                 options: { adaptive: false }
                            }
                        ]
                    },
                    onShow: function(instance) {
                        document.querySelectorAll('[data-tippy-root]').forEach(function(tooltip) {
                            if (tooltip._tippy && tooltip._tippy !== instance) {
                                tooltip._tippy.hide();
                             }
                             }
                         },
                         });
                        {
                    }
                            name: 'flip',
                });
                            options: {
            });
                                fallbackPlacements: ['top', 'bottom', 'right', 'left']
        }
    };
   
    // Модуль data-text подсказок
    var DataTooltipsModule = {
        init: function() {
            var elements = document.querySelectorAll('.data-tooltip[data-text]');
            if (elements.length === 0) return;
           
            MediaWikiTooltips.load(function() {
                elements.forEach(function(element) {
                    var tooltipText = element.getAttribute('data-text');
                    if (!tooltipText || !tooltipText.trim()) return;
                   
                    tippy(element, {
                        content: tooltipText,
                        allowHTML: true,
                        interactive: false,
                        placement: 'top',
                        maxWidth: 300,
                        theme: 'data-tooltip-theme',
                        arrow: true,
                        duration: [200, 150],
                        delay: [0, 50]
                    });
                });
            });
           
            // Наблюдатель за новыми элементами
            var observer = new MutationObserver(function(mutations) {
                var shouldReinit = false;
                mutations.forEach(function(mutation) {
                    mutation.addedNodes.forEach(function(node) {
                        if (node.nodeType === 1) {
                            if (node.classList && node.classList.contains('data-tooltip') && node.hasAttribute('data-text')) {
                                shouldReinit = true;
                            } else if (node.querySelectorAll) {
                                var newElements = node.querySelectorAll('.data-tooltip[data-text]');
                                if (newElements.length > 0) {
                                    shouldReinit = true;
                                }
                             }
                             }
                         }
                         }
                     ]
                     });
                });
               
                if (shouldReinit) {
                    setTimeout(function() { DataTooltipsModule.init(); }, 100);
                 }
                 }
             });
             });
         });
           
            observer.observe(document.body, {
                childList: true,
                subtree: true
            });
         }
    };
   
    // Инициализация всех модулей
    function initAllModules() {
        SidebarModule.init();
        AccessTooltipsModule.init();
        LawTooltipsModule.init();
        DataTooltipsModule.init();
     }
     }
 
   
(function() {
    // Запуск
    'use strict';
    if (document.readyState === 'loading') {
   
        document.addEventListener('DOMContentLoaded', initAllModules);
    if (window.lawTooltipsLoaded) return;
    } else {
    window.lawTooltipsLoaded = true;
        initAllModules();
   
    }
    function loadTippy(callback) {
   
        if (window.tippy) {
})();
            callback();
            return;
        }
       
        var popperScript = document.createElement('script');
        popperScript.src = 'https://unpkg.com/@popperjs/core@2/dist/umd/popper.min.js';
        popperScript.onload = function() {
            var tippyScript = document.createElement('script');
            tippyScript.src = 'https://unpkg.com/tippy.js@6/dist/tippy-bundle.umd.min.js';
            tippyScript.onload = callback;
            document.head.appendChild(tippyScript);
        };
        document.head.appendChild(popperScript);
       
        var tippyCSS = document.createElement('link');
        tippyCSS.rel = 'stylesheet';
        tippyCSS.href = 'https://unpkg.com/tippy.js@6/dist/tippy.css';
        document.head.appendChild(tippyCSS);
    }
   
    function extractLawDataFromPage() {
        var lawData = {};
        var detailTables = document.querySelectorAll('.mw-collapsible-content table');
       
        detailTables.forEach(function(table) {
            var rows = table.querySelectorAll('tr');
           
            rows.forEach(function(row) {
                var cells = row.querySelectorAll('td');
                if (cells.length >= 3) {
                    var crimeCell = cells[0];
                    var descriptionCell = cells[1];
                    var exampleCell = cells[2];
                   
                    var anchor = crimeCell.querySelector('[id]');
                    if (anchor) {
                        var lawCode = anchor.id;
                        var titleElement = crimeCell.querySelector('b');
                       
                        if (titleElement && lawCode.match(/^\d{3}$/)) {
                            var titleText = titleElement.textContent.trim();
                           
                            var lawTitle = titleText.replace(/^\d{3}\s*/, '').replace(/^\d{3}/, '').trim();
                           
                            var description = descriptionCell.textContent.trim();
                           
                            var examples = [];
                            var exampleItems = exampleCell.querySelectorAll('li');
                            exampleItems.forEach(function(item) {
                                var text = item.textContent.trim();
                                if (text) {
                                    examples.push(text);
                                }
                            });
                           
                            lawData[lawCode] = {
                                title: lawTitle,
                                description: description,
                                examples: examples
                            };
                        }
                    }
                }
            });
        });
       
        return lawData;
    }
   
    function createTooltipContent(lawCode, lawData) {
        var data = lawData[lawCode];
        if (!data) return null;
       
        var html = '<div class="law-tooltip">';
        html += '<h4 class="law-tooltip-title">' + lawCode + ' - ' + data.title + '</h4>';
        html += '<p class="law-tooltip-description">' + data.description + '</p>';
       
        if (data.examples && data.examples.length > 0) {
            html += '<div class="law-tooltip-examples">';
            html += '<strong>Примеры:</strong>';
            html += '<ul>';
            data.examples.slice(0, 5).forEach(function(example) {
                html += '<li>' + example + '</li>';
            });
            html += '</ul>';
            html += '</div>';
        }
        html += '</div>';
       
        return html;
    }
   
    function initTooltips() {
        var lawData = extractLawDataFromPage();
        var tableCells = document.querySelectorAll('.law-tooltips td, .law-tooltips th');
       
        tableCells.forEach(function(cell) {
            var link = cell.querySelector('a[href*="#"]');
           
            if (link) {
                var href = link.getAttribute('href');
                var match = href.match(/#(\d{3})/);
               
                if (match) {
                    var lawCode = match[1];
                    var tooltipContent = createTooltipContent(lawCode, lawData);
                   
                    if (tooltipContent) {
                        cell.classList.add('law-cell-with-tooltip');
                       
                        cell.addEventListener('click', function(e) {
                            e.preventDefault();
                            window.location.hash = lawCode;
                        });
                       
                        tippy(cell, {
                            content: tooltipContent,
                            allowHTML: true,
                            interactive: true,
                            placement: 'top',
                            maxWidth: 400,
                            theme: 'law-theme',
                            arrow: true,
                            duration: [200, 150],
                            delay: [0, 50],
                            appendTo: document.body,
                            boundary: 'viewport',
                            popperOptions: {
                                strategy: 'fixed',
                                modifiers: [
                                    {
                                        name: 'preventOverflow',
                                        options: {
                                            boundary: 'viewport',
                                            padding: 20,
                                            altAxis: true,
                                            altBoundary: true
                                        }
                                    },
                                    {
                                        name: 'flip',
                                        options: {
                                            fallbackPlacements: ['bottom', 'left', 'right']
                                        }
                                    },
                                    {
                                        name: 'computeStyles',
                                        options: {
                                            adaptive: false
                                        }
                                    }
                                ]
                            },
                            onShow: function(instance) {
                                document.querySelectorAll('[data-tippy-root]').forEach(function(tooltip) {
                                    if (tooltip._tippy && tooltip._tippy !== instance) {
                                        tooltip._tippy.hide();
                                    }
                                });
                            }
                        });
                    }
                }
            }
        });
    }
   
    function init() {
        loadTippy(function() {
            initTooltips();
        });
    }
   
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
   
})();
(function() {
    'use strict';
   
    console.log('Data tooltip script loading...');
   
    if (window.dataTextTooltipsLoaded) {
        console.log('Script already loaded, skipping...');
        return;
    }
    window.dataTextTooltipsLoaded = true;
   
    function loadTippy(callback) {
        console.log('Loading Tippy.js...');
        if (window.tippy) {
            console.log('Tippy.js already loaded');
            callback();
            return;
        }
       
        var popperScript = document.createElement('script');
        popperScript.src = 'https://unpkg.com/@popperjs/core@2/dist/umd/popper.min.js';
        popperScript.onload = function() {
            console.log('Popper.js loaded');
            var tippyScript = document.createElement('script');
            tippyScript.src = 'https://unpkg.com/tippy.js@6/dist/tippy-bundle.umd.min.js';
            tippyScript.onload = function() {
                console.log('Tippy.js loaded');
                callback();
            };
            tippyScript.onerror = function() {
                console.error('Failed to load Tippy.js');
            };
            document.head.appendChild(tippyScript);
        };
        popperScript.onerror = function() {
            console.error('Failed to load Popper.js');
        };
        document.head.appendChild(popperScript);
       
        var tippyCSS = document.createElement('link');
        tippyCSS.rel = 'stylesheet';
        tippyCSS.href = 'https://unpkg.com/tippy.js@6/dist/tippy.css';
        document.head.appendChild(tippyCSS);
    }
   
    function initTooltips() {
        console.log('Initializing tooltips...');
        var elements = document.querySelectorAll('.data-tooltip[data-text]');
        console.log('Found elements:', elements.length);
       
        elements.forEach(function(element, index) {
            var tooltipText = element.getAttribute('data-text');
            console.log('Element', index + 1, ':', element, 'Text:', tooltipText);
           
            if (tooltipText && tooltipText.trim()) {
                try {
                    tippy(element, {
                        content: tooltipText,
                        allowHTML: true,
                        interactive: false,
                        placement: 'top',
                        maxWidth: 300,
                        theme: 'data-tooltip-theme',
                        arrow: true,
                        duration: [200, 150],
                        delay: [0, 50],
                        onShow: function(instance) {
                            console.log('Tooltip showing for:', instance.reference);
                        },
                        onHide: function(instance) {
                            console.log('Tooltip hiding for:', instance.reference);
                        }
                    });
                    console.log('Tooltip created for element', index + 1);
                } catch (error) {
                    console.error('Error creating tooltip:', error);
                }
            }
        });
       
        console.log('Tooltips initialization complete');
    }
   
    function init() {
        console.log('Initializing data tooltip system...');
        loadTippy(function() {
            console.log('Tippy loaded, initializing tooltips...');
            setTimeout(function() {
                initTooltips();
            }, 100);
        });
    }
   
    if (document.readyState === 'loading') {
        console.log('Document loading, waiting for DOMContentLoaded...');
        document.addEventListener('DOMContentLoaded', init);
    } else {
        console.log('Document ready, initializing immediately...');
        init();
    }
   
})();
});

Версия от 12:06, 27 сентября 2025

(function() {
    'use strict';
    
    // Глобальный менеджер для Tippy.js
    window.MediaWikiTooltips = {
        loaded: false,
        callbacks: [],
        
        load: function(callback) {
            if (this.loaded && window.tippy) {
                callback();
                return;
            }
            
            this.callbacks.push(callback);
            
            if (this.loading) return;
            this.loading = true;
            
            var self = this;
            var popperScript = document.createElement('script');
            popperScript.src = 'https://unpkg.com/@popperjs/core@2/dist/umd/popper.min.js';
            popperScript.onload = function() {
                var tippyScript = document.createElement('script');
                tippyScript.src = 'https://unpkg.com/tippy.js@6/dist/tippy-bundle.umd.min.js';
                tippyScript.onload = function() {
                    self.loaded = true;
                    self.loading = false;
                    self.callbacks.forEach(function(cb) { cb(); });
                    self.callbacks = [];
                };
                document.head.appendChild(tippyScript);
            };
            document.head.appendChild(popperScript);
            
            var tippyCSS = document.createElement('link');
            tippyCSS.rel = 'stylesheet';
            tippyCSS.href = 'https://unpkg.com/tippy.js@6/dist/tippy.css';
            document.head.appendChild(tippyCSS);
        }
    };
    
    // Модуль боковой панели
    var SidebarModule = {
        init: function() {
            var buttons = document.querySelectorAll('.боковая-панель-кнопка');
            var sections = document.querySelectorAll('.боковая-панель-раздел');
            
            if (buttons.length === 0) return;
            
            buttons.forEach(function(button) {
                button.addEventListener('click', function() {
                    var targetId = this.dataset.target;
                    
                    buttons.forEach(function(btn) { btn.classList.remove('active'); });
                    this.classList.add('active');
                    
                    sections.forEach(function(section) { section.classList.remove('default'); });
                    var targetSection = document.getElementById(targetId);
                    if (targetSection) {
                        targetSection.classList.add('default');
                    }
                });
            });
            
            buttons[0].click();
        }
    };
    
    // Модуль подсказок допусков
    var AccessTooltipsModule = {
        init: function() {
            var containers = document.querySelectorAll('.допуск-контейнер');
            if (containers.length === 0) return;
            
            MediaWikiTooltips.load(function() {
                containers.forEach(function(container) {
                    var contentElement = container.querySelector('.допуск-подсказка');
                    if (!contentElement) return;
                    
                    var content = contentElement.innerHTML;
                    tippy(container, {
                        content: content,
                        allowHTML: true,
                        interactive: true,
                        placement: 'auto',
                        maxWidth: 500,
                        theme: 'dark',
                        arrow: true,
                        duration: [200, 200],
                        popperOptions: {
                            modifiers: [
                                {
                                    name: 'preventOverflow',
                                    options: { padding: 8 }
                                },
                                {
                                    name: 'flip',
                                    options: {
                                        fallbackPlacements: ['top', 'bottom', 'right', 'left']
                                    }
                                }
                            ]
                        }
                    });
                });
            });
        }
    };
    
    // Модуль подсказок законов
    var LawTooltipsModule = {
        init: function() {
            var tableCells = document.querySelectorAll('.law-tooltips td, .law-tooltips th');
            if (tableCells.length === 0) return;
            
            MediaWikiTooltips.load(function() {
                var lawData = LawTooltipsModule.extractLawData();
                LawTooltipsModule.initCellTooltips(tableCells, lawData);
            });
        },
        
        extractLawData: function() {
            var lawData = {};
            var detailTables = document.querySelectorAll('.mw-collapsible-content table');
            
            detailTables.forEach(function(table) {
                var rows = table.querySelectorAll('tr');
                
                rows.forEach(function(row) {
                    var cells = row.querySelectorAll('td');
                    if (cells.length < 3) return;
                    
                    var crimeCell = cells[0];
                    var descriptionCell = cells[1];
                    var exampleCell = cells[2];
                    
                    var anchor = crimeCell.querySelector('[id]');
                    if (!anchor) return;
                    
                    var lawCode = anchor.id;
                    var titleElement = crimeCell.querySelector('b');
                    
                    if (titleElement && lawCode.match(/^\d{3}$/)) {
                        var titleText = titleElement.textContent.trim();
                        var lawTitle = titleText.replace(/^\d{3}\s*/, '').replace(/^\d{3}/, '').trim();
                        var description = descriptionCell.textContent.trim();
                        
                        var examples = [];
                        var exampleItems = exampleCell.querySelectorAll('li');
                        exampleItems.forEach(function(item) {
                            var text = item.textContent.trim();
                            if (text) examples.push(text);
                        });
                        
                        lawData[lawCode] = {
                            title: lawTitle,
                            description: description,
                            examples: examples
                        };
                    }
                });
            });
            
            return lawData;
        },
        
        createTooltipContent: function(lawCode, lawData) {
            var data = lawData[lawCode];
            if (!data) return null;
            
            var html = '<div class="law-tooltip">';
            html += '<h4 class="law-tooltip-title">' + lawCode + ' - ' + data.title + '</h4>';
            html += '<p class="law-tooltip-description">' + data.description + '</p>';
            
            if (data.examples && data.examples.length > 0) {
                html += '<div class="law-tooltip-examples">';
                html += '<strong>Примеры:</strong><ul>';
                data.examples.slice(0, 5).forEach(function(example) {
                    html += '<li>' + example + '</li>';
                });
                html += '</ul></div>';
            }
            html += '</div>';
            
            return html;
        },
        
        initCellTooltips: function(tableCells, lawData) {
            tableCells.forEach(function(cell) {
                var link = cell.querySelector('a[href*="#"]');
                if (!link) return;
                
                var href = link.getAttribute('href');
                var match = href.match(/#(\d{3})/);
                if (!match) return;
                
                var lawCode = match[1];
                var tooltipContent = LawTooltipsModule.createTooltipContent(lawCode, lawData);
                if (!tooltipContent) return;
                
                cell.classList.add('law-cell-with-tooltip');
                
                cell.addEventListener('click', function(e) {
                    e.preventDefault();
                    window.location.hash = lawCode;
                });
                
                tippy(cell, {
                    content: tooltipContent,
                    allowHTML: true,
                    interactive: true,
                    placement: 'top',
                    maxWidth: 400,
                    theme: 'law-theme',
                    arrow: true,
                    duration: [200, 150],
                    delay: [0, 50],
                    appendTo: document.body,
                    boundary: 'viewport',
                    popperOptions: {
                        strategy: 'fixed',
                        modifiers: [
                            {
                                name: 'preventOverflow',
                                options: {
                                    boundary: 'viewport',
                                    padding: 20,
                                    altAxis: true,
                                    altBoundary: true
                                }
                            },
                            {
                                name: 'flip',
                                options: {
                                    fallbackPlacements: ['bottom', 'left', 'right']
                                }
                            },
                            {
                                name: 'computeStyles',
                                options: { adaptive: false }
                            }
                        ]
                    },
                    onShow: function(instance) {
                        document.querySelectorAll('[data-tippy-root]').forEach(function(tooltip) {
                            if (tooltip._tippy && tooltip._tippy !== instance) {
                                tooltip._tippy.hide();
                            }
                        });
                    }
                });
            });
        }
    };
    
    // Модуль data-text подсказок
    var DataTooltipsModule = {
        init: function() {
            var elements = document.querySelectorAll('.data-tooltip[data-text]');
            if (elements.length === 0) return;
            
            MediaWikiTooltips.load(function() {
                elements.forEach(function(element) {
                    var tooltipText = element.getAttribute('data-text');
                    if (!tooltipText || !tooltipText.trim()) return;
                    
                    tippy(element, {
                        content: tooltipText,
                        allowHTML: true,
                        interactive: false,
                        placement: 'top',
                        maxWidth: 300,
                        theme: 'data-tooltip-theme',
                        arrow: true,
                        duration: [200, 150],
                        delay: [0, 50]
                    });
                });
            });
            
            // Наблюдатель за новыми элементами
            var observer = new MutationObserver(function(mutations) {
                var shouldReinit = false;
                mutations.forEach(function(mutation) {
                    mutation.addedNodes.forEach(function(node) {
                        if (node.nodeType === 1) {
                            if (node.classList && node.classList.contains('data-tooltip') && node.hasAttribute('data-text')) {
                                shouldReinit = true;
                            } else if (node.querySelectorAll) {
                                var newElements = node.querySelectorAll('.data-tooltip[data-text]');
                                if (newElements.length > 0) {
                                    shouldReinit = true;
                                }
                            }
                        }
                    });
                });
                
                if (shouldReinit) {
                    setTimeout(function() { DataTooltipsModule.init(); }, 100);
                }
            });
            
            observer.observe(document.body, {
                childList: true,
                subtree: true
            });
        }
    };
    
    // Инициализация всех модулей
    function initAllModules() {
        SidebarModule.init();
        AccessTooltipsModule.init();
        LawTooltipsModule.init();
        DataTooltipsModule.init();
    }
    
    // Запуск
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initAllModules);
    } else {
        initAllModules();
    }
    
})();