Нет описания правки |
Нет описания правки |
||
Строка 537: | Строка 537: | ||
fieldsContainer.appendChild(gridContainer); | fieldsContainer.appendChild(gridContainer); | ||
if (container.firstChild) { | if (container.firstChild) { |
Версия от 12:47, 1 октября 2025
(function() {
'use strict';
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.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
}
},
{
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();
}
});
}
});
});
}
};
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
});
}
};
var CopyTextModule = {
init: function() {
CopyTextModule.initDirectElements();
CopyTextModule.initAutoContainers();
},
initDirectElements: function() {
var elements = document.querySelectorAll('.copyable-text');
if (elements.length === 0) return;
elements.forEach(function(element) {
CopyTextModule.setupElement(element);
});
},
initAutoContainers: function() {
var containers = document.querySelectorAll('.copyable-pre-container');
if (containers.length === 0) return;
containers.forEach(function(container) {
CopyTextModule.processContainerPre(container);
});
// Наблюдатель за динамически появляющимися элементами
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
mutation.addedNodes.forEach(function(node) {
if (node.nodeType === 1) {
// Проверяем сам элемент
if (node.tagName === 'PRE') {
var container = node.closest('.copyable-pre-container');
if (container && !node.classList.contains('copyable-text')) {
node.classList.add('copyable-text');
CopyTextModule.setupElement(node);
}
}
// Проверяем дочерние элементы
else if (node.querySelectorAll) {
var containers = node.querySelectorAll('.copyable-pre-container');
containers.forEach(function(container) {
CopyTextModule.processContainerPre(container);
});
// Также проверяем pre внутри уже существующих контейнеров
var preElements = node.querySelectorAll('.copyable-pre-container pre');
preElements.forEach(function(pre) {
if (!pre.classList.contains('copyable-text')) {
pre.classList.add('copyable-text');
CopyTextModule.setupElement(pre);
}
});
}
}
});
// Обрабатываем изменения атрибутов (например, style="display: none" -> "")
if (mutation.type === 'attributes' && mutation.attributeName === 'style') {
var target = mutation.target;
if (target.style.display !== 'none') {
var containers = target.querySelectorAll('.copyable-pre-container');
containers.forEach(function(container) {
CopyTextModule.processContainerPre(container);
});
}
}
});
});
observer.observe(document.body, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ['style']
});
},
processContainerPre: function(container) {
var preElements = container.querySelectorAll('pre');
preElements.forEach(function(pre) {
if (!pre.classList.contains('copyable-text')) {
pre.classList.add('copyable-text');
CopyTextModule.setupElement(pre);
}
});
},
setupElement: function(element) {
element.style.cursor = 'pointer';
element.addEventListener('click', CopyTextModule.handleClick);
var isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
if (isIOS) {
element.style.webkitUserSelect = 'text';
element.style.userSelect = 'text';
}
},
handleClick: function(e) {
e.preventDefault();
var element = this;
var textToCopy = element.textContent.trim();
if (navigator.clipboard && window.isSecureContext) {
navigator.clipboard.writeText(textToCopy).then(function() {
CopyTextModule.showNotification(element);
}).catch(function(err) {
console.error('Ошибка при копировании: ', err);
CopyTextModule.fallbackCopy(textToCopy, element);
});
} else {
CopyTextModule.fallbackCopy(textToCopy, element);
}
element.classList.add('copying');
setTimeout(function() {
element.classList.remove('copying');
}, 200);
},
fallbackCopy: function(text, element) {
var textArea = document.createElement('textarea');
textArea.value = text;
textArea.style.position = 'fixed';
textArea.style.top = '-9999px';
textArea.style.left = '-9999px';
textArea.style.width = '2em';
textArea.style.height = '2em';
textArea.style.padding = '0';
textArea.style.border = 'none';
textArea.style.outline = 'none';
textArea.style.boxShadow = 'none';
textArea.style.background = 'transparent';
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
try {
var successful = document.execCommand('copy');
if (successful) {
CopyTextModule.showNotification(element);
} else {
console.error('Не удалось скопировать текст');
}
} catch (err) {
console.error('Ошибка при копировании: ', err);
}
document.body.removeChild(textArea);
},
showNotification: function(element) {
var existingNotifications = document.querySelectorAll('.copy-notification');
existingNotifications.forEach(function(notification) {
notification.remove();
});
var notification = document.createElement('div');
notification.className = 'copy-notification';
notification.textContent = 'Текст скопирован!';
document.body.appendChild(notification);
var rect = element.getBoundingClientRect();
var isMobile = window.innerWidth <= 768;
if (isMobile) {
notification.style.position = 'fixed';
notification.style.top = '20px';
notification.style.left = '50%';
notification.style.transform = 'translateX(-50%) translateY(-10px)';
notification.style.zIndex = '10000';
} else {
notification.style.position = 'absolute';
notification.style.top = (rect.top + window.scrollY - 40) + 'px';
notification.style.left = (rect.left + window.scrollX) + 'px';
notification.style.zIndex = '9999';
}
setTimeout(function() {
notification.classList.add('show');
}, 10);
setTimeout(function() {
notification.classList.remove('show');
setTimeout(function() {
if (notification.parentNode) {
notification.remove();
}
}, 300);
}, 2000);
}
};
var DocumentAutoFillModule = {
init: function() {
this.processExistingContainers();
this.observeNewContainers();
this.startTimeUpdateTimer();
},
processExistingContainers: function() {
var containers = document.querySelectorAll('.copyable-pre-container.auto-fill-enabled');
containers.forEach(function(container) {
this.setupAutoFillContainer(container);
}.bind(this));
},
setupAutoFillContainer: function(container) {
if (container.querySelector('.document-fields-container')) {
return;
}
var fieldsContainer = document.createElement('div');
fieldsContainer.className = 'document-fields-container';
var gridContainer = document.createElement('div');
gridContainer.className = 'fields-grid';
var siteNumberField = this.createField('site-number', 'Номер участка:', 'Введите номер участка...', false);
var authorField = this.createField('author', 'Автор документа:', 'Введите ваше имя...', true);
var positionField = this.createField('position', 'Должность:', 'Введите вашу должность...', true);
var signatureField = this.createField('signature', 'Подпись:', 'Введите подпись...', true);
gridContainer.appendChild(siteNumberField.container);
gridContainer.appendChild(authorField.container);
gridContainer.appendChild(positionField.container);
gridContainer.appendChild(signatureField.container);
fieldsContainer.appendChild(gridContainer);
if (container.firstChild) {
container.insertBefore(fieldsContainer, container.firstChild);
} else {
container.appendChild(fieldsContainer);
}
setTimeout(function() {
this.applyAllFieldsToContainer(container);
}.bind(this), 100);
},
createField: function(fieldType, labelText, placeholder, shouldCache) {
var fieldContainer = document.createElement('div');
fieldContainer.className = 'field-container';
var label = document.createElement('label');
label.textContent = labelText;
label.htmlFor = fieldType + '-input';
var input = document.createElement('input');
input.type = 'text';
input.id = fieldType + '-input';
input.className = 'field-input ' + fieldType + '-input';
input.placeholder = placeholder;
if (shouldCache) {
var savedValue = localStorage.getItem('document' + this.capitalizeFirstLetter(fieldType));
if (savedValue) {
input.value = savedValue;
}
}
input.addEventListener('input', function() {
var value = input.value.trim();
if (shouldCache) {
localStorage.setItem('document' + this.capitalizeFirstLetter(fieldType), value);
}
}.bind(this));
fieldContainer.appendChild(label);
fieldContainer.appendChild(input);
return {
container: fieldContainer,
input: input,
type: fieldType,
shouldCache: shouldCache
};
},
capitalizeFirstLetter: function(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
},
applyAllFieldsToContainer: function(container) {
var fieldsContainer = container.querySelector('.document-fields-container');
if (!fieldsContainer) return;
var siteNumber = fieldsContainer.querySelector('.site-number-input').value.trim();
var author = fieldsContainer.querySelector('.author-input').value.trim();
var position = fieldsContainer.querySelector('.position-input').value.trim();
var signature = fieldsContainer.querySelector('.signature-input').value.trim();
this.autoFillAllDocumentsInContainer(container, {
siteNumber: siteNumber,
author: author,
position: position,
signature: signature
});
},
autoFillAllDocumentsInContainer: function(container, fields) {
var preElements = container.querySelectorAll('pre');
preElements.forEach(function(preElement) {
this.autoFillDocument(preElement, fields);
}.bind(this));
},
autoFillDocument: function(preElement, fields) {
if (!preElement) return;
var originalContent = preElement.textContent || preElement.innerText;
if (!this.isDocumentTemplate(originalContent)) {
return;
}
var updatedContent = this.fillDocumentContent(originalContent, fields);
if (updatedContent !== originalContent) {
preElement.textContent = updatedContent;
}
},
isDocumentTemplate: function(text) {
return text.includes('SCP') &&
text.includes('Обезопасить. Удержать. Сохранить.') &&
text.includes('Автор документа:') &&
text.includes('Дата и время:');
},
fillDocumentContent: function(content, fields) {
var currentDateTime = this.getCurrentDateTime();
content = content.replace(
/(\[bold\]Дата и время:\[\/bold\])([^\n]*)/g,
'$1 ' + currentDateTime
);
if (fields.siteNumber) {
content = content.replace(
/Участок-([^|\n]*)/g,
'Участок-' + fields.siteNumber
);
}
if (fields.author) {
content = content.replace(
/(\[bold\]Автор документа:\[\/bold\])([^\n]*)/g,
'$1 ' + fields.author
);
} else {
content = content.replace(
/(\[bold\]Автор документа:\[\/bold\])([^\n]*)/g,
'$1'
);
}
if (fields.position) {
content = content.replace(
/(\[bold\]Должность:\[\/bold\])([^\n]*)/g,
'$1 ' + fields.position
);
} else {
content = content.replace(
/(\[bold\]Должность:\[\/bold\])([^\n]*)/g,
'$1'
);
}
if (fields.signature) {
content = content.replace(
/(\[bold\]Подпись:\[\/bold\])[^\n]*/g,
'$1 ' + fields.signature
);
} else {
content = content.replace(
/(\[bold\]Подпись:\[\/bold\])([^\n]*)/g,
'$1_____'
);
}
return content;
},
getCurrentDateTime: function() {
var now = new Date();
var day = String(now.getDate()).padStart(2, '0');
var month = String(now.getMonth() + 1).padStart(2, '0');
var year = now.getFullYear();
var hours = String(now.getHours()).padStart(2, '0');
var minutes = String(now.getMinutes()).padStart(2, '0');
return hours + ':' + minutes + ', ' + day + '.' + month + '.' + year;
},
startTimeUpdateTimer: function() {
var self = this;
function updateTimeIfNeeded() {
var containers = document.querySelectorAll('.copyable-pre-container.auto-fill-enabled');
if (containers.length > 0) {
containers.forEach(function(container) {
var fieldsContainer = container.querySelector('.document-fields-container');
if (fieldsContainer) {
self.applyAllFieldsToContainer(container);
}
});
}
}
this.timeUpdateInterval = setInterval(updateTimeIfNeeded, 5000);
document.addEventListener('visibilitychange', function() {
if (!document.hidden) {
updateTimeIfNeeded();
}
});
window.addEventListener('focus', updateTimeIfNeeded);
},
stopTimeUpdateTimer: function() {
if (this.timeUpdateInterval) {
clearInterval(this.timeUpdateInterval);
this.timeUpdateInterval = null;
}
},
observeNewContainers: function() {
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
mutation.addedNodes.forEach(function(node) {
if (node.nodeType === 1) {
if (node.classList &&
node.classList.contains('copyable-pre-container') &&
node.classList.contains('auto-fill-enabled')) {
setTimeout(function() {
DocumentAutoFillModule.setupAutoFillContainer(node);
}, 100);
}
else if (node.querySelectorAll) {
var containers = node.querySelectorAll('.copyable-pre-container.auto-fill-enabled');
containers.forEach(function(container) {
setTimeout(function() {
DocumentAutoFillModule.setupAutoFillContainer(container);
}, 100);
});
}
}
});
});
});
observer.observe(document.body, {
childList: true,
subtree: true
});
}
};
window.DocumentAutoFill = {
refreshAll: function() {
var containers = document.querySelectorAll('.copyable-pre-container.auto-fill-enabled');
containers.forEach(function(container) {
DocumentAutoFillModule.applyAllFieldsToContainer(container);
});
},
clearAllNames: function() {
localStorage.removeItem('documentAuthor');
localStorage.removeItem('documentPosition');
localStorage.removeItem('documentSignature');
var inputs = document.querySelectorAll('.author-input, .position-input, .signature-input');
inputs.forEach(function(input) {
input.value = '';
});
window.DocumentAutoFill.refreshAll();
},
startTimeUpdates: function() {
DocumentAutoFillModule.startTimeUpdateTimer();
},
stopTimeUpdates: function() {
DocumentAutoFillModule.stopTimeUpdateTimer();
}
};
function initAllModules() {
SidebarModule.init();
AccessTooltipsModule.init();
LawTooltipsModule.init();
DataTooltipsModule.init();
CopyTextModule.init();
DocumentAutoFillModule.init(); // Добавляем новый модуль
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initAllModules);
} else {
initAllModules();
}
})();