Mediawiki:common.js
| Строка 1: | Строка 1: | ||
/** | |||
* Если CDN недоступен: залей на вики popper.min.js, tippy-bundle.umd.min.js, tippy.css (через Загрузить файл), | |||
* затем в консоли или в начале скрипта задай: | |||
* MediaWikiTooltips.baseUrl = "https://fire.station.wiki.shizainc.com/wiki/Special:FilePath/"; | |||
* (подставь свой домен вики) | |||
*/ | |||
(function () { | (function () { | ||
"use strict"; | "use strict"; | ||
| Строка 26: | Строка 32: | ||
tippy: "/tippy.js/6.3.7/tippy-bundle.umd.min.js", | tippy: "/tippy.js/6.3.7/tippy-bundle.umd.min.js", | ||
css: "/tippy.js/6.3.7/tippy.css", | css: "/tippy.js/6.3.7/tippy.css", | ||
}, | }, | ||
]; | ]; | ||
| Строка 62: | Строка 56: | ||
self.loading = false; | self.loading = false; | ||
self.callbacks.forEach(function (cb) { | self.callbacks.forEach(function (cb) { | ||
try { | try { cb(); } catch (e) {} | ||
}); | }); | ||
self.callbacks = []; | self.callbacks = []; | ||
| Строка 82: | Строка 72: | ||
if (cdnIndex + 1 < cdns.length) { | if (cdnIndex + 1 < cdns.length) { | ||
cdnIndex++; | cdnIndex++; | ||
loadPopper(); | loadPopper(); | ||
} else { | } else { | ||
| Строка 104: | Строка 90: | ||
tippyCSS.rel = "stylesheet"; | tippyCSS.rel = "stylesheet"; | ||
tippyCSS.href = urlJoin(cdn.base, cdn.css); | tippyCSS.href = urlJoin(cdn.base, cdn.css); | ||
tippyCSS.onerror = function () { | tippyCSS.onerror = function () {}; | ||
document.head.appendChild(tippyCSS); | document.head.appendChild(tippyCSS); | ||
runCallbacks(); | runCallbacks(); | ||
}; | }; | ||
| Строка 126: | Строка 104: | ||
if (cdnIndex + 1 < cdns.length) { | if (cdnIndex + 1 < cdns.length) { | ||
cdnIndex++; | cdnIndex++; | ||
loadPopper(); | loadPopper(); | ||
} else { | } else { | ||
| Строка 220: | Строка 194: | ||
var LawTooltipsModule = { | var LawTooltipsModule = { | ||
init: function () { | init: function() { | ||
var tableCells = document.querySelectorAll('.law-tooltips td, .law-tooltips th'); | |||
var tableCells = document.querySelectorAll( | if (tableCells.length === 0) return; | ||
MediaWikiTooltips.load(function() { | |||
if (tableCells.length === 0) | |||
function | |||
var lawData = LawTooltipsModule.extractLawData(); | var lawData = LawTooltipsModule.extractLawData(); | ||
LawTooltipsModule.initCellTooltips(tableCells, lawData); | |||
}); | }); | ||
}, | }, | ||
extractLawData: function () { | 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.innerHTML.trim(); | |||
var examples = []; | |||
var exampleItems = exampleCell.querySelectorAll('li'); | |||
exampleItems.forEach(function(item) { | |||
var html = item.innerHTML.trim(); | |||
// Удаляем все <br> теги | |||
html = html.replace(/<br\s*\/?>/gi, ''); | |||
if (html) examples.push(html); | |||
}); | |||
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>'; // Теперь example содержит HTML | |||
}); | |||
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 | |||
} | |||
initCellTooltips: function (tableCells, lawData) { | }, | ||
{ | |||
name: 'flip', | |||
options: { | |||
fallbackPlacements: ['bottom', 'left', 'right'] | |||
tableCells.forEach(function (cell) { | } | ||
var link = cell.querySelector('a[href*="#"]'); | }, | ||
if (!link) return; | { | ||
name: 'computeStyles', | |||
options: { adaptive: false } | |||
var href = link.getAttribute( | } | ||
var match = href.match(/#(\d{3})/); | ] | ||
if (!match) return; | }, | ||
onShow: function(instance) { | |||
document.querySelectorAll('[data-tippy-root]').forEach(function(tooltip) { | |||
var lawCode = match[1]; | if (tooltip._tippy && tooltip._tippy !== instance) { | ||
var tooltipContent = LawTooltipsModule.createTooltipContent( | tooltip._tippy.hide(); | ||
} | |||
}); | |||
} | |||
if (!tooltipContent) return; | |||
cell.classList.add( | |||
cell.addEventListener( | |||
e.preventDefault(); | |||
window.location.hash = lawCode; | |||
}); | |||
tippy(cell, { | |||
content: tooltipContent, | |||
allowHTML: true, | |||
interactive: true, | |||
placement: | |||
maxWidth: 400, | |||
theme: | |||
arrow: true, | |||
duration: [200, 150], | |||
delay: [0, 50], | |||
appendTo: document.body, | |||
boundary: | |||
popperOptions: { | |||
strategy: | |||
modifiers: [ | |||
{ | |||
name: | |||
options: { | |||
boundary: | |||
padding: 20, | |||
altAxis: true, | |||
altBoundary: true | |||
} | |||
}, | |||
{ | |||
name: | |||
options: { | |||
fallbackPlacements: [ | |||
} | |||
}, | |||
{ | |||
name: | |||
options: { adaptive: false } | |||
} | |||
] | |||
}, | |||
onShow: function (instance) { | |||
document | |||
} | |||
}); | }); | ||
}); | }); | ||
} | |||
} | |||
}; | }; | ||
| Строка 1297: | Строка 1137: | ||
); | ); | ||
var categories = {}; | var categories = {}; | ||
punishmentSections.forEach( | punishmentSections.forEach( | ||
| Строка 1313: | Строка 1147: | ||
if (punishmentMatch) { | if (punishmentMatch) { | ||
var punishmentText = punishmentMatch[1].trim(); | var punishmentText = punishmentMatch[1].trim(); | ||
var categoryInfo = | var categoryInfo = | ||
| Строка 1327: | Строка 1157: | ||
if (categoryKey) { | if (categoryKey) { | ||
categories[categoryKey] = categoryInfo; | categories[categoryKey] = categoryInfo; | ||
} | } | ||
} | } | ||
| Строка 1337: | Строка 1162: | ||
}.bind(this), | }.bind(this), | ||
); | ); | ||
// Применяем найденную информацию к законам | // Применяем найденную информацию к законам | ||
| Строка 2377: | Строка 2200: | ||
if (!FireworksConstructor) { | if (!FireworksConstructor) { | ||
return; | return; | ||
} | } | ||