Нет описания правки |
Нет описания правки |
||
Строка 1: | Строка 1: | ||
(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; | |||
var | |||
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 = []; | |||
options: { | 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(); | |||
} | |||
})(); | |||
Версия от 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();
}
})();