|
|
| Строка 452: |
Строка 452: |
| }); | | }); |
| } | | } |
| });
| |
| }
| |
| // Функции для добавления кастомных заголовков в TOC
| |
| function addHeadingsWithTOC() {
| |
| mw.hook('wikipage.content').add(function($content) {
| |
| var $toc = $('#toc ul'); // Находим TOC
| |
| $toc.empty();
| |
| var $headings = $content.find('h1, h2, h3, h4, h5, h6, .custom-heading');
| |
| var tocCounters = [];
| |
| var $currentList = $toc; // Текущий список для вставки элементов
| |
| var levelStack = []; // Стек для отслеживания уровней заголовков
| |
| var maxLevel = 7; // Изначально максимальный уровень не определён
| |
|
| |
| // Первый проход для нахождения минимального уровня заголовков
| |
| $headings.each(function() {
| |
| var $heading = $(this);
| |
| var level;
| |
| if ($heading.hasClass('custom-heading')) {
| |
| level = 1; // Для кастомных заголовков
| |
| } else {
| |
| var tagName = $heading.prop('tagName').toLowerCase();
| |
| level = parseInt(tagName.charAt(1), 10); // Определяем уровень h1-h6
| |
| }
| |
| if (level < maxLevel) {
| |
| maxLevel = level; // Находим минимальный уровень заголовков
| |
| }
| |
| });
| |
|
| |
| function updateCounters(level) {
| |
| if (level > tocCounters.length) {
| |
| tocCounters.push(0);
| |
| } else if (level < tocCounters.length) {
| |
| tocCounters = tocCounters.slice(0, level);
| |
| }
| |
| tocCounters[level - 1]++;
| |
| }
| |
|
| |
| function getSectionNumber() {
| |
| return tocCounters.join('.');
| |
| }
| |
|
| |
| function createNestedList($parent) {
| |
| var $nestedList = $('<ul>');
| |
| $parent.append($nestedList);
| |
| return $nestedList;
| |
| }
| |
|
| |
| function closeNestedLists(targetLevel) {
| |
| while (levelStack.length > 0 && levelStack[levelStack.length - 1] >= targetLevel) {
| |
| $currentList = $currentList.parent().closest('ul');
| |
| levelStack.pop();
| |
| }
| |
| }
| |
|
| |
| $headings.each(function() {
| |
| var $heading = $(this);
| |
| var level;
| |
| var $headlineSpan = $heading.find('span.mw-headline');
| |
|
| |
| if ($heading.hasClass('custom-heading')) {
| |
| level = 1;
| |
| var customId = $heading.attr('id') || 'custom-heading-' + getSectionNumber();
| |
| $heading.attr('id', customId);
| |
| } else if ($headlineSpan.length > 0) {
| |
| var tagName = $heading.prop('tagName').toLowerCase();
| |
| level = parseInt(tagName.charAt(1), 10);
| |
| var existingId = $headlineSpan.attr('id');
| |
|
| |
| if (!existingId) {
| |
| var sectionId = 'heading-' + getSectionNumber();
| |
| $headlineSpan.attr('id', sectionId);
| |
| }
| |
| } else {
| |
| return; // Пропускаем элементы без заголовков
| |
| }
| |
|
| |
| updateCounters(level);
| |
|
| |
| var headingText = $headlineSpan.text().trim() || $heading.text().trim();
| |
|
| |
| if (headingText.length > 0) {
| |
| // Закрываем вложенные списки, если текущий уровень меньше
| |
| closeNestedLists(level);
| |
|
| |
| var tocItem = $('<li>').addClass('toclevel-' + (level - maxLevel)).append(
| |
| $('<a>').attr('href', '#' + ($headlineSpan.attr('id') || customId)).append(
| |
| $('<span>').addClass('tocnumber').text(getSectionNumber()),
| |
| $('<span>').addClass('toctext').text(headingText)
| |
| )
| |
| );
| |
|
| |
| // Если текущий уровень равен максимальному (высший уровень), добавляем его в основной список
| |
| if (level === maxLevel) {
| |
| $toc.append(tocItem); // Главный список
| |
| $currentList = $toc; // Сбрасываем на основной список
| |
| } else {
| |
| // Если уровень ниже максимального, создаем вложенный список
| |
| if (level > levelStack[levelStack.length - 1]) {
| |
| var $nestedList = createNestedList($currentList);
| |
| $currentList = $nestedList;
| |
| }
| |
| $currentList.append(tocItem);
| |
| }
| |
|
| |
| // Добавляем уровень в стек для дальнейшего отслеживания
| |
| levelStack.push(level);
| |
| }
| |
| });
| |
| }); | | }); |
| } | | } |