Mediawiki:common.js

Вернуться

Строка 106: Строка 106:
     };
     };
      
      
    var LawTooltipsModule = {
var LawTooltipsModule = {
        init: function() {
    init: function () {
            var tableCells = document.querySelectorAll('.law-tooltips td');
        var tableCells = document.querySelectorAll('.law-tooltips td, .law-tooltips th');
            if (tableCells.length === 0) return;
        if (tableCells.length === 0) return;
           
 
            MediaWikiTooltips.load(function() {
        MediaWikiTooltips.load(function () {
                var lawData = LawTooltipsModule.extractLawData();
            var lawData = LawTooltipsModule.extractLawData();
                LawTooltipsModule.initCellTooltips(tableCells, lawData);
            LawTooltipsModule.initCellTooltips(tableCells, lawData);
        });
    },
 
    extractLawData: function () {
        var lawData = {};
        var crimeIdSpans = document.querySelectorAll('table.wikitable span[id^="§_"]');
 
        crimeIdSpans.forEach(function (span) {
            var lawCode = span.id;
            if (!lawCode) return;
 
            var tr = span.closest('tr');
            if (!tr) return;
 
            var cells = tr.querySelectorAll('td');
            if (cells.length < 3) return;
 
            var crimeCell = cells[0];
            var descriptionCell = cells[1];
            var exampleCell = cells[2];
 
            var title = LawTooltipsModule.extractTitleFromCrimeCell(crimeCell);
            if (!title) return;
 
            var description = (descriptionCell.innerHTML || '').trim();
            var examples = LawTooltipsModule.extractExamplesFromExampleCell(exampleCell);
 
            lawData[lawCode] = {
                title: title,
                description: description,
                examples: examples
            };
        });
 
        return lawData;
    },
 
    extractTitleFromCrimeCell: function (crimeCell) {
        var b = crimeCell.querySelector('b');
        var text = (b ? b.textContent : crimeCell.textContent) || '';
        text = text.replace(/\s+/g, ' ').trim();
 
        // Пример текста: "§ 1.1 Оскорбительное поведение"
        text = text.replace(/^§\s*[\d]+(?:\.\s*[\d]+)*\s*/,'').trim();
        return text;
    },
 
    extractExamplesFromExampleCell: function (exampleCell) {
        var examples = [];
        var liItems = exampleCell.querySelectorAll('li');
 
        if (liItems.length > 0) {
            liItems.forEach(function (item) {
                var html = (item.innerHTML || '').trim();
                html = html.replace(/<br\s*\/?>/gi, '');
                html = html.trim();
                if (html) examples.push(html);
             });
             });
         },
            return examples;
          
         }
         extractLawData: function() {
 
    var lawData = {};
         // На случай, если вместо <li> будет иной формат
    var detailTables = document.querySelectorAll('.mw-collapsible-content table');
         var fallback = (exampleCell.innerHTML || '').trim();
   
        fallback = fallback.replace(/<br\s*\/?>/gi, '').trim();
    detailTables.forEach(function(table) {
        if (fallback) examples.push(fallback);
        var rows = table.querySelectorAll('tr');
 
       
        return examples;
        rows.forEach(function(row) {
    },
            var cells = row.querySelectorAll('td');
 
            if (cells.length < 3) return;
    formatLawCode: function (lawCode) {
           
        // §_1.1 -> § 1.1
            var crimeCell = cells[0];
        return (lawCode || '').replace(/^§_/, '§ ');
            var descriptionCell = cells[1];
    },
            var exampleCell = cells[2];
 
           
     createTooltipContent: function (lawCode, lawData) {
            var anchor = crimeCell.querySelector('[id]');
        var data = lawData[lawCode];
            if (!anchor) return;
        if (!data) return null;
           
 
            var lawCode = anchor.id;
        var displayCode = LawTooltipsModule.formatLawCode(lawCode);
            var titleElement = crimeCell.querySelector('b');
 
           
        var html = '<div class="law-tooltip">';
            if (titleElement && lawCode.match(/^\d{3}$/)) {
        html += '<h4 class="law-tooltip-title">' + displayCode + ' - ' + data.title + '</h4>';
                var titleText = titleElement.textContent.trim();
        html += '<p class="law-tooltip-description">' + (data.description || '') + '</p>';
                var lawTitle = titleText.replace(/^\d{3}\s*/, '').replace(/^\d{3}/, '').trim();
 
                var description = descriptionCell.innerHTML.trim();
        if (data.examples && data.examples.length > 0) {
               
            html += '<div class="law-tooltip-examples">';
                var examples = [];
            html += '<strong>Примеры:</strong><ul>';
                var exampleItems = exampleCell.querySelectorAll('li');
            data.examples.slice(0, 5).forEach(function (example) {
exampleItems.forEach(function(item) {
                html += '<li>' + example + '</li>';
    var html = item.innerHTML.trim();
            });
    // Удаляем все <br> теги
            html += '</ul></div>';
    html = html.replace(/<br\s*\/?>/gi, '');
        }
    if (html) examples.push(html);
 
});
        html += '</div>';
               
        return html;
                lawData[lawCode] = {
    },
                    title: lawTitle,
 
                    description: description,
    initCellTooltips: function (tableCells, lawData) {
                    examples: examples
        tableCells.forEach(function (cell) {
                };
            if (cell.dataset.lawTooltipAttached === '1') return;
            }
 
        });
            var link = cell.querySelector('a[href^="#"]');
    });
            if (!link) return;
   
 
    return lawData;
            var href = link.getAttribute('href') || '';
},
            var match = href.match(/^#(.+)$/);
       
            if (!match) return;
     createTooltipContent: function(lawCode, lawData) {
 
    var data = lawData[lawCode];
            var lawCode = match[1];
    if (!data) return null;
            if (!lawCode) return;
   
 
    var html = '<div class="law-tooltip">';
            var tooltipContent = LawTooltipsModule.createTooltipContent(lawCode, lawData);
    html += '<h4 class="law-tooltip-title">' + lawCode + ' - ' + data.title + '</h4>';
            if (!tooltipContent) return;
    html += '<p class="law-tooltip-description">' + data.description + '</p>';
 
   
            cell.dataset.lawTooltipAttached = '1';
    if (data.examples && data.examples.length > 0) {
            cell.classList.add('law-cell-with-tooltip');
        html += '<div class="law-tooltip-examples">';
 
        html += '<strong>Примеры:</strong><ul>';
            cell.addEventListener('click', function (e) {
        data.examples.slice(0, 5).forEach(function(example) {
                e.preventDefault();
            html += '<li>' + example + '</li>'; // Теперь example содержит HTML
                window.location.hash = lawCode;
        });
            });
        html += '</ul></div>';
 
    }
            tippy(cell, {
    html += '</div>';
                content: tooltipContent,
   
                allowHTML: true,
    return html;
                interactive: true,
},
                placement: 'top',
       
                maxWidth: 400,
        initCellTooltips: function(tableCells, lawData) {
                theme: 'law-theme',
            tableCells.forEach(function(cell) {
                arrow: true,
                var link = cell.querySelector('a[href*="#"]');
                duration: [200, 150],
                if (!link) return;
                delay: [0, 50],
               
                appendTo: document.body,
                var href = link.getAttribute('href');
                boundary: 'viewport',
                var match = href.match(/#(\d{3})/);
                popperOptions: {
                if (!match) return;
                    strategy: 'fixed',
               
                    modifiers: [
                var lawCode = match[1];
                        {
                var tooltipContent = LawTooltipsModule.createTooltipContent(lawCode, lawData);
                            name: 'preventOverflow',
                if (!tooltipContent) return;
                            options: {
               
                                boundary: 'viewport',
                cell.classList.add('law-cell-with-tooltip');
                                padding: 20,
               
                                altAxis: true,
                cell.addEventListener('click', function(e) {
                                altBoundary: true
                    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) {
                            name: 'flip',
                        document.querySelectorAll('[data-tippy-root]').forEach(function(tooltip) {
                             options: {
                             if (tooltip._tippy && tooltip._tippy !== instance) {
                                 fallbackPlacements: ['bottom', 'left', 'right']
                                 tooltip._tippy.hide();
                             }
                             }
                         });
                         },
                     }
                        {
                 });
                            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();
                        }
                     });
                 }
             });
             });
         }
         });
     };
     }
};
      
      
     var DataTooltipsModule = {
     var DataTooltipsModule = {