Mediawiki:common.js
| Строка 106: | Строка 106: | ||
}; | }; | ||
var LawTooltipsModule = { | |||
init: function() { | |||
console.log('[LawTooltips] init()'); | |||
var tableCells = document.querySelectorAll('.law-tooltips td, .law-tooltips th'); | |||
console.log('[LawTooltips] .law-tooltips ячеек:', tableCells.length); | |||
if (tableCells.length === 0) { | |||
console.warn('[LawTooltips] Нет ячеек .law-tooltips — выход'); | |||
return; | |||
} | |||
function run() { | |||
console.log('[LawTooltips] run() — извлечение данных...'); | |||
var lawData = LawTooltipsModule.extractLawData(); | |||
var count = Object.keys(lawData).length; | |||
console.log('[LawTooltips] Загружено записей законов:', count, count ? Object.keys(lawData).slice(0, 10).join(', ') + (count > 10 ? '...' : '') : ''); | |||
if (count > 0) { | |||
LawTooltipsModule.initCellTooltips(tableCells, lawData); | |||
return true; | |||
} | |||
return false; | |||
} | |||
if (typeof MediaWikiTooltips === 'undefined') { | |||
console.error('[LawTooltips] MediaWikiTooltips не найден — тултипы не загрузятся'); | |||
run(); | |||
return; | |||
} | |||
MediaWikiTooltips.load(function() { | |||
console.log('[LawTooltips] MediaWikiTooltips.load вызван'); | |||
if (run()) { | |||
console.log('[LawTooltips] Инициализация с первой попытки'); | |||
return; | |||
} | |||
setTimeout(function() { | |||
if (run()) { | |||
console.log('[LawTooltips] Инициализация после 300ms'); | |||
return; | |||
} | |||
setTimeout(function() { | |||
if (run()) console.log('[LawTooltips] Инициализация после 800ms'); | |||
else console.warn('[LawTooltips] Данные законов не найдены после всех попыток'); | |||
}, 500); | |||
}, 300); | |||
}); | |||
}, | |||
extractLawData: function() { | |||
var lawData = {}; | |||
var containers = document.querySelectorAll('.mw-collapsible'); | |||
console.log('[LawTooltips] extractLawData: коллапсибл-блоков:', containers.length); | |||
containers.forEach(function(block) { | |||
var content = block.querySelector('.mw-collapsible-content'); | |||
if (content && block.classList.contains('mw-collapsed')) { | |||
block.classList.remove('mw-collapsed'); | |||
var toggle = content.querySelector('.mw-collapsible-toggle'); | |||
if (toggle) toggle.setAttribute('aria-expanded', 'true'); | |||
} | |||
}); | |||
var detailTables = document.querySelectorAll('.mw-collapsible-content table'); | |||
console.log('[LawTooltips] extractLawData: таблиц в .mw-collapsible-content:', detailTables.length); | |||
detailTables.forEach(function(table, tableIndex) { | |||
if (table.classList.contains('law-tooltips')) { | |||
console.log('[LawTooltips] extractLawData: таблица', tableIndex, '— пропуск (law-tooltips)'); | |||
return; | |||
} | |||
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}$/)) return; | |||
var titleText = titleElement.textContent.trim(); | |||
var lawTitle = titleText.replace(/^\d{3}\s*/, '').replace(/^\d{3}/, '').trim(); | |||
var description = descriptionCell.innerHTML.trim(); | |||
var examples = []; | |||
var exampleItems = exampleCell.querySelectorAll('li'); | |||
exampleItems.forEach(function(item) { | |||
var html = item.innerHTML.trim().replace(/<br\s*\/?>/gi, ''); | |||
if (html) examples.push(html); | |||
}); | |||
lawData[lawCode] = { | |||
title: lawTitle, | |||
description: description, | |||
examples: examples | |||
}; | |||
}); | |||
}); | |||
console.log('[LawTooltips] extractLawData: итого кодов:', Object.keys(lawData).length); | |||
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) { | |||
var withLink = 0, withMatch = 0, withContent = 0, tooltipsCreated = 0; | |||
tableCells.forEach(function(cell) { | |||
var link = cell.querySelector('a[href*="#"]'); | |||
if (!link) return; | |||
withLink++; | |||
var href = link.getAttribute('href'); | |||
var match = href.match(/#(\d{3})/); | |||
if (!match) return; | |||
withMatch++; | |||
var lawCode = match[1]; | |||
var tooltipContent = LawTooltipsModule.createTooltipContent(lawCode, lawData); | |||
if (!tooltipContent) return; | |||
withContent++; | |||
cell.classList.add('law-cell-with-tooltip'); | |||
tooltipsCreated++; | |||
cell.addEventListener('click', function(e) { | |||
e.preventDefault(); | |||
window.location.hash = lawCode; | |||
}); | |||
if (typeof tippy === 'undefined') { | |||
console.error('[LawTooltips] tippy не найден — подключи библиотеку Tippy.js'); | |||
return; | |||
} | |||
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(); | |||
} | |||
}); | |||
} | |||
}); | |||
}); | |||
console.log('[LawTooltips] initCellTooltips: ячеек с ссылкой', withLink, '| с #XXX', withMatch, '| с данными', withContent, '| тултипов создано', tooltipsCreated); | |||
} | |||
}; | |||