MediaWiki:Common.js: различия между версиями

Нет описания правки
мНет описания правки
Строка 102: Строка 102:
return getXHRInfo(connect).then(function(serverData) {
return getXHRInfo(connect).then(function(serverData) {
var unixStartRound = getUnixTime(serverData.round_start_time);
var unixStartRound = getUnixTime(serverData.round_start_time);
var timeDisplay = unixStartRound ? secondsToDHM(currentUnixTime -
var timeDisplay = unixStartRound ? secondsToDHM(currentUnixTime - unixStartRound) : "–";
unixStartRound) : "–";
var currentPlayers = serverData.players;
var currentPlayers = serverData.players;
var maxPlayers = serverData.soft_max_players;
var maxPlayers = serverData.soft_max_players;
// Вычисляем процент
// Вычисляем процент
var percentage = maxPlayers > 0 ? Math.round((currentPlayers /
var percentage = maxPlayers > 0 ? Math.round((currentPlayers / maxPlayers) * 100) : 0;
maxPlayers) * 100) : 0;
// Форматируем строку с количеством игроков
// Форматируем строку с количеством игроков
var playersDisplay = currentPlayers && maxPlayers ? currentPlayers + '/' +
var playersDisplay = currentPlayers && maxPlayers ? currentPlayers + '/' + maxPlayers : "–";
maxPlayers : "–";
// Функция для проверки на пустые данные
// Функция для проверки на пустые данные
function checkValue(value) {
function checkValue(value) {
Строка 155: Строка 152:


function getServerTime() {
function getServerTime() {
return fetch(
return fetch('https://station14.ru/api.php?action=query&meta=siteinfo&siprop=general&format=json').then(
'https://station14.ru/api.php?action=query&meta=siteinfo&siprop=general&format=json'
function(response) {
).then(function(response) {
return response.json();
return response.json();
}).then(function(data) {
}).then(function(data) {
return getUnixTime(data.query.general.time);
return getUnixTime(data.query.general.time);
});
});
Строка 171: Строка 167:
2: "Завершение"
2: "Завершение"
};
};
serverStatusFrame.querySelector(".serverInfoRoundSet").textContent = "#" +
serverStatusFrame.querySelector(".serverInfoRoundSet").textContent = "#" + serverObj.round;
serverObj.round;
serverStatusFrame.querySelector(".serverStatusSet").textContent = statusText[serverObj.status] ||
serverStatusFrame.querySelector(".serverStatusSet").textContent = statusText[
"Неизвестный статус";
serverObj.status] || "Неизвестный статус";
serverStatusFrame.querySelector(".serverMapSet").textContent = serverObj.map;
serverStatusFrame.querySelector(".serverMapSet").textContent = serverObj.map;
serverStatusFrame.querySelector(".serverTimeSet").textContent = serverObj.time;
serverStatusFrame.querySelector(".serverTimeSet").textContent = serverObj.time;
Строка 183: Строка 178:
return server.name === serverName;
return server.name === serverName;
});
});
var connectionStringElement = serverStatusFrame.querySelector(
var connectionStringElement = serverStatusFrame.querySelector(".serverConnectSet");
".serverConnectSet");
if (connectionStringElement) {
if (connectionStringElement) {
connectionStringElement.textContent = serverData ? serverData.serverconnect :
connectionStringElement.textContent = serverData ? serverData.serverconnect : '-'; // Устанавливаем строку подключения
'-'; // Устанавливаем строку подключения
}
}
// Обновляем прогресс-бар
// Обновляем прогресс-бар
Строка 233: Строка 226:


function escapeAndMinifyCSS(css) {
function escapeAndMinifyCSS(css) {
  return css
return css.replace(/\\/g, '\\\\') // Экранируем обратный слэш
    .replace(/\\/g, '\\\\') // Экранируем обратный слэш
.replace(/\n/g, '') // Удаляем переносы строк (по желанию)
    .replace(/\n/g, '') // Удаляем переносы строк (по желанию)
.replace(/\/\*[\s\S]*?\*\//g, '') // Удаляем комментарии
    .replace(/\/\*[\s\S]*?\*\//g, '') // Удаляем комментарии
.replace(/\s+/g, ' ') // Заменяем множественные пробелы на один
    .replace(/\s+/g, ' ') // Заменяем множественные пробелы на один
.trim(); // Удаляем пробелы в начале и конце
    .trim(); // Удаляем пробелы в начале и конце
}
}
const addedStyles = new Set();
const addedStyles = new Set();


function customCSS(textCSS) {
function customCSS(textCSS) {
  const escapedCSS = escapeAndMinifyCSS(textCSS); // Экранируем CSS
const escapedCSS = escapeAndMinifyCSS(textCSS); // Экранируем CSS
 
// Проверяем, был ли уже добавлен этот CSS
  // Проверяем, был ли уже добавлен этот CSS
if (!addedStyles.has(escapedCSS)) {
  if (!addedStyles.has(escapedCSS)) {
addedStyles.add(escapedCSS); // Добавляем в множество уникальных стилей
    addedStyles.add(escapedCSS); // Добавляем в множество уникальных стилей
const styleSheet = document.createElement("style");
 
styleSheet.textContent = escapedCSS;
    const styleSheet = document.createElement("style");
document.head.appendChild(styleSheet);
    styleSheet.textContent = escapedCSS;
}
    document.head.appendChild(styleSheet);
  }
}
}


Строка 291: Строка 280:
return iframe;
return iframe;
}
}
// Функция для увеличения яркости цвета
// Функция для увеличения яркости цвета
function brightenColor(color, factor) {
function brightenColor(color, factor) {
    function getBrightness(r, g, b) {
function getBrightness(r, g, b) {
        return 0.2126 * r + 0.7152 * g + 0.0722 * b;
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
    }
}
 
var rgbValues = color.match(/\d+(\.\d+)?/g);
    var rgbValues = color.match(/\d+(\.\d+)?/g);
var r = parseInt(rgbValues[0], 10);
    var r = parseInt(rgbValues[0], 10);
var g = parseInt(rgbValues[1], 10);
    var g = parseInt(rgbValues[1], 10);
var b = parseInt(rgbValues[2], 10);
    var b = parseInt(rgbValues[2], 10);
var a = rgbValues.length === 4 ? parseFloat(rgbValues[3]) : 1; // Обработка альфа-канала
    var a = rgbValues.length === 4 ? parseFloat(rgbValues[3]) : 1; // Обработка альфа-канала
var brightness = getBrightness(r, g, b);
 
if (factor === undefined) {
    var brightness = getBrightness(r, g, b);
if (brightness < 30) {
 
if (r > g && r > b) {
    if (factor === undefined) {
factor = 1.1 + (30 - brightness) / 300; // Красный доминирует
        if (brightness < 30) {
} else if (g > r && g > b) {
            if (r > g && r > b) {
factor = 1.1 + (30 - brightness) / 200; // Зеленый доминирует
                factor = 1.1 + (30 - brightness) / 300; // Красный доминирует
} else {
            } else if (g > r && g > b) {
factor = 1.1 + (30 - brightness) / 50; // Темный цвет с доминированием синего
                factor = 1.1 + (30 - brightness) / 200; // Зеленый доминирует
}
            } else {
} else if (brightness <= 55) {
                factor = 1.1 + (30 - brightness) / 50;   // Темный цвет с доминированием синего
factor = 1.09;
            }
} else if (brightness < 140) {
        } else if (brightness <= 55) {
factor = 1.045;
            factor = 1.09;
} else if (brightness < 180) {
        } else if (brightness < 140) {
factor = 1.02;
            factor = 1.045;
} else {
        } else if (brightness < 180) {
factor = 1.0;
            factor = 1.02;
}
        } else {
}
            factor = 1.0;
r = Math.min(255, Math.floor(r * factor));
        }
g = Math.min(255, Math.floor(g * factor));
    }
b = Math.min(255, Math.floor(b * factor));
 
return a < 1 ? 'rgba(' + r + ', ' + g + ', ' + b + ', ' + a + ')' : 'rgb(' + r + ', ' + g + ', ' + b + ')';
    r = Math.min(255, Math.floor(r * factor));
    g = Math.min(255, Math.floor(g * factor));
    b = Math.min(255, Math.floor(b * factor));
 
    return a < 1 ? 'rgba(' + r + ', ' + g + ', ' + b + ', ' + a + ')' : 'rgb(' + r + ', ' + g + ', ' + b + ')';
}
}
// Функция для подсветки ячеек в таблице при наведении
// Функция для подсветки ячеек в таблице при наведении
function applyHighlighting() {
function applyHighlighting() {
    if (/Mobi|Android/i.test(navigator.userAgent)) {
if (/Mobi|Android/i.test(navigator.userAgent)) {
        return;
return;
    }
}
 
var tables = document.querySelectorAll('.wikitable:not(.no-highlight-table)');
    var tables = document.querySelectorAll('.wikitable:not(.no-highlight-table)');
Array.prototype.forEach.call(tables, function(table) {
 
var tbody = table.querySelector('tbody');
    Array.prototype.forEach.call(tables, function(table) {
var thead = table.querySelector('thead');
        var tbody = table.querySelector('tbody');
var noHeader = table.classList.contains('no-header-table');
        var thead = table.querySelector('thead');
if (tbody) {
        var noHeader = table.classList.contains('no-header-table');
// Получаем все строки <tr> внутри первого уровня <tbody>
 
var rows = Array.prototype.slice.call(tbody.querySelectorAll('tr')).filter(function(row) {
        if (tbody) {
// Проверяем, что <tr> находится на первом уровне, и исключаем строки с вложенными таблицами
            // Получаем все строки <tr> внутри первого уровня <tbody>
return row.parentElement === tbody && !row.querySelector('table');
            var rows = Array.prototype.slice.call(tbody.querySelectorAll('tr')).filter(function(row) {
});
                // Проверяем, что <tr> находится на первом уровне, и исключаем строки с вложенными таблицами
// Пропускаем первую строку, если нет <thead> и нет класса 'no-header-table'
                return row.parentElement === tbody && !row.querySelector('table');
var topLevelRows = (!thead && !noHeader) ? rows.slice(1) : rows;
            });
var hasInvalidRowspan = false;
 
var hasTooManyRowspan = false;
            // Пропускаем первую строку, если нет <thead> и нет класса 'no-header-table'
// Проверка на ошибки в rowspan
            var topLevelRows = (!thead && !noHeader) ? rows.slice(1) : rows;
Array.prototype.forEach.call(topLevelRows, function(row) {
 
var cells = Array.prototype.slice.call(row.querySelectorAll('td, th')).filter(function(cell) {
            var hasInvalidRowspan = false;
return !cell.classList.contains('mobile');
            var hasTooManyRowspan = false;
});
 
var cellCount = cells.length;
            // Проверка на ошибки в rowspan
var rowspanCount = cells.filter(function(cell) {
            Array.prototype.forEach.call(topLevelRows, function(row) {
return cell.hasAttribute('rowspan') && cell.getAttribute('rowspan') !== '1';
                var cells = Array.prototype.slice.call(row.querySelectorAll('td, th')).filter(function(cell) {
}).length;
                    return !cell.classList.contains('mobile');
// Проверка на слишком большое количество rowspan или неправильное расположение rowspan
                });
if (rowspanCount > 2 || (cellCount <= 3 && rowspanCount > 1)) {
 
hasTooManyRowspan = true;
                var cellCount = cells.length;
return;
 
}
                var rowspanCount = cells.filter(function(cell) {
var hasValidRowspanEdge = cells.some(function(cell, index) {
                    return cell.hasAttribute('rowspan') && cell.getAttribute('rowspan') !== '1';
return cell.hasAttribute('rowspan') && cell.getAttribute('rowspan') !== '1' && (index === 0 ||
                }).length;
index === cells.length - 1);
 
});
                // Проверка на слишком большое количество rowspan или неправильное расположение rowspan
if (!hasValidRowspanEdge && cells.some(function(cell, index) {
                if (rowspanCount > 2 || (cellCount <= 3 && rowspanCount > 1)) {
return cell.hasAttribute('rowspan') && cell.getAttribute('rowspan') !== '1' && index > 0 && index <
                    hasTooManyRowspan = true;
cells.length - 1;
                    return;
})) {
                }
hasInvalidRowspan = true;
 
}
                var hasValidRowspanEdge = cells.some(function(cell, index) {
});
                    return cell.hasAttribute('rowspan') && cell.getAttribute('rowspan') !== '1' && (index === 0 || index === cells.length - 1);
// Если есть ошибки в rowspan, выходим
                });
if (hasTooManyRowspan || hasInvalidRowspan) return;
 
// Обработка наведения на строки и ячейки
                if (!hasValidRowspanEdge && cells.some(function(cell, index) {
Array.prototype.forEach.call(topLevelRows, function(row, rowIndex) {
                    return cell.hasAttribute('rowspan') && cell.getAttribute('rowspan') !== '1' && index > 0 && index < cells.length - 1;
var cells = Array.prototype.slice.call(row.querySelectorAll('td, th'));
                })) {
// Сохраняем оригинальные стили для каждой ячейки
                    hasInvalidRowspan = true;
var originalStyles = cells.map(function(cell) {
                }
return {
            });
backgroundColor: getComputedStyle(cell).backgroundColor,
 
color: getComputedStyle(cell).color
            // Если есть ошибки в rowspan, выходим
};
            if (hasTooManyRowspan || hasInvalidRowspan) return;
});
 
// Наведение на строку (tr)
            // Обработка наведения на строки и ячейки
row.addEventListener('mouseover', function() {
            Array.prototype.forEach.call(topLevelRows, function(row, rowIndex) {
highlightRow(row, rowIndex, true);
                var cells = Array.prototype.slice.call(row.querySelectorAll('td, th'));
});
 
row.addEventListener('mouseout', function() {
                // Сохраняем оригинальные стили для каждой ячейки
highlightRow(row, rowIndex, false);
                var originalStyles = cells.map(function(cell) {
});
                    return {
// Наведение на ячейки с rowspan
                        backgroundColor: getComputedStyle(cell).backgroundColor,
Array.prototype.forEach.call(cells, function(cell, cellIndex) {
                        color: getComputedStyle(cell).color
if (cell.hasAttribute('rowspan') && parseInt(cell.getAttribute('rowspan')) > 1) {
                    };
var rowspan = parseInt(cell.getAttribute('rowspan'));
                });
// Обработка rowspan ячейки
 
cell.addEventListener('mouseover', function() {
                // Наведение на строку (tr)
// Отключаем обработку строки при наведении на rowspan ячейку
                row.addEventListener('mouseover', function() {
row.classList.add('highlighted');
                    highlightRow(row, rowIndex, true);
highlightRowspanArea(rowIndex, cellIndex, rowspan, true);
                });
});
                row.addEventListener('mouseout', function() {
cell.addEventListener('mouseout', function() {
                    highlightRow(row, rowIndex, false);
// Восстанавливаем состояние строки при уходе курсора
                });
row.classList.remove('highlighted');
 
highlightRowspanArea(rowIndex, cellIndex, rowspan, false);
                // Наведение на ячейки с rowspan
});
                Array.prototype.forEach.call(cells, function(cell, cellIndex) {
}
                    if (cell.hasAttribute('rowspan') && parseInt(cell.getAttribute('rowspan')) > 1) {
});
                        var rowspan = parseInt(cell.getAttribute('rowspan'));
// Функция подсветки строки (только текущее tr)
                        // Обработка rowspan ячейки
function highlightRow(row, rowIndex, highlight) {
                        cell.addEventListener('mouseover', function() {
if (row.classList.contains('highlighted')) return; // Избегаем повторного применения подсветки
                            // Отключаем обработку строки при наведении на rowspan ячейку
var rowCells = Array.prototype.slice.call(row.querySelectorAll('td, th'));
                            row.classList.add('highlighted');
Array.prototype.forEach.call(rowCells, function(cell, cellIndex) {
                            highlightRowspanArea(rowIndex, cellIndex, rowspan, true);
// Подсвечиваем только ячейки, не имеющие атрибут rowSpan
                        });
if (!cell.hasAttribute('rowspan')) {
                        cell.addEventListener('mouseout', function() {
var cellStyle = getComputedStyle(cell);
                            // Восстанавливаем состояние строки при уходе курсора
cell.style.setProperty('background-color', highlight ? brightenColor(cellStyle.backgroundColor) :
                            row.classList.remove('highlighted');
originalStyles[cellIndex].backgroundColor, 'important');
                            highlightRowspanArea(rowIndex, cellIndex, rowspan, false);
cell.style.setProperty('color', highlight ? brightenColor(cellStyle.color) : originalStyles[
                        });
cellIndex].color, 'important');
                    }
}
                });
});
 
}
                // Функция подсветки строки (только текущее tr)
// Функция подсветки для ячеек с rowspan (подсвечивает все строки, которые охватывает ячейка)
                function highlightRow(row, rowIndex, highlight) {
function highlightRowspanArea(rowIndex, cellIndex, rowspan, highlight) {
                    if (row.classList.contains('highlighted')) return; // Избегаем повторного применения подсветки
for (var i = 0; i < rowspan; i++) {
 
var targetRow = topLevelRows[rowIndex + i];
                    var rowCells = Array.prototype.slice.call(row.querySelectorAll('td, th'));
if (targetRow) {
 
var targetCells = Array.prototype.slice.call(targetRow.querySelectorAll('td, th'));
                    Array.prototype.forEach.call(rowCells, function(cell, cellIndex) {
// Обработка ячейки в каждой строке, затронутой rowspan
                        // Подсвечиваем только ячейки, не имеющие атрибут rowSpan
Array.prototype.forEach.call(targetCells, function(targetCell, targetCellIndex) {
                        if (!cell.hasAttribute('rowspan')) {
var targetCellStyle = getComputedStyle(targetCell);
                            var cellStyle = getComputedStyle(cell);
// Сохраняем оригинальные стили для каждой ячейки, если подсветка включена
                            cell.style.setProperty('background-color', highlight ? brightenColor(cellStyle.backgroundColor) : originalStyles[cellIndex].backgroundColor, 'important');
if (highlight) {
                            cell.style.setProperty('color', highlight ? brightenColor(cellStyle.color) : originalStyles[cellIndex].color, 'important');
targetCell.originalBackground = targetCellStyle.backgroundColor;
                        }
targetCell.originalColor = targetCellStyle.color;
                    });
}
                }
// Применяем подсветку или восстанавливаем оригинальные стили
 
targetCell.style.setProperty('background-color', highlight ? brightenColor(targetCellStyle.backgroundColor) :
                // Функция подсветки для ячеек с rowspan (подсвечивает все строки, которые охватывает ячейка)
targetCell.originalBackground, 'important');
                function highlightRowspanArea(rowIndex, cellIndex, rowspan, highlight) {
targetCell.style.setProperty('color', highlight ? brightenColor(targetCellStyle.color) :
                    for (var i = 0; i < rowspan; i++) {
targetCell.originalColor, 'important');
                        var targetRow = topLevelRows[rowIndex + i];
});
                        if (targetRow) {
}
                            var targetCells = Array.prototype.slice.call(targetRow.querySelectorAll('td, th'));
}
 
}
                            // Обработка ячейки в каждой строке, затронутой rowspan
});
                            Array.prototype.forEach.call(targetCells, function(targetCell, targetCellIndex) {
}
                                var targetCellStyle = getComputedStyle(targetCell);
});
 
                                // Сохраняем оригинальные стили для каждой ячейки, если подсветка включена
                                if (highlight) {
                                    targetCell.originalBackground = targetCellStyle.backgroundColor;
                                    targetCell.originalColor = targetCellStyle.color;
                                }
 
                                // Применяем подсветку или восстанавливаем оригинальные стили
                                targetCell.style.setProperty('background-color', highlight ? brightenColor(targetCellStyle.backgroundColor) : targetCell.originalBackground, 'important');
                                targetCell.style.setProperty('color', highlight ? brightenColor(targetCellStyle.color) : targetCell.originalColor, 'important');
                            });
                        }
                    }
                }
            });
        }
    });
}
}
// Функции для добавления кастомных заголовков в TOC
// Функции для добавления кастомных заголовков в TOC
function addHeadingsWithTOC() {
function addHeadingsWithTOC() {
    mw.hook('wikipage.content').add(function($content) {
mw.hook('wikipage.content').add(function($content) {
        var $toc = $('#toc ul'); // Находим TOC
var $toc = $('#toc ul'); // Находим TOC
        $toc.empty();
$toc.empty();
 
// Ищем заголовки h1 - h6 и элементы с классом .custom-heading
        // Ищем заголовки h1 - h6 и элементы с классом .custom-heading
var $headings = $content.find('h1, h2, h3, h4, h5, h6, .custom-heading');
        var $headings = $content.find('h1, h2, h3, h4, h5, h6, .custom-heading');
var tocCounters = [0]; // Счётчики для уровней заголовков
        var tocCounters = [0]; // Счётчики для уровней заголовков
var lastLevel = 1; // Уровень предыдущего заголовка
        var lastLevel = 1; // Уровень предыдущего заголовка
var $currentList = $toc; // Текущий список для вложенности
        var $currentList = $toc; // Текущий список для вложенности
// Функция для обновления счётчиков для текущего уровня
 
function updateCounters(level) {
        // Функция для обновления счётчиков для текущего уровня
if (level > lastLevel) {
        function updateCounters(level) {
tocCounters.push(0); // Добавляем новый уровень
            if (level > lastLevel) {
} else if (level < lastLevel) {
                tocCounters.push(0); // Добавляем новый уровень
tocCounters = tocCounters.slice(0, level); // Убираем лишние уровни
            } else if (level < lastLevel) {
}
                tocCounters = tocCounters.slice(0, level); // Убираем лишние уровни
tocCounters[level - 1]++;
            }
lastLevel = level;
            tocCounters[level - 1]++;
}
            lastLevel = level;
// Функция для получения номера секции в стиле "1", "1.1", "1.1.1"
        }
function getSectionNumber() {
 
return tocCounters.join('.');
        // Функция для получения номера секции в стиле "1", "1.1", "1.1.1"
}
        function getSectionNumber() {
// Функция для создания нового <ul> для вложенного уровня
            return tocCounters.join('.');
function createNestedList($parent) {
        }
var $nestedList = $('<ul>');
 
$parent.append($nestedList);
        // Функция для создания нового <ul> для вложенного уровня
return $nestedList;
        function createNestedList($parent) {
}
            var $nestedList = $('<ul>');
// Перебираем все заголовки и элементы с классом .custom-heading
            $parent.append($nestedList);
$headings.each(function() {
            return $nestedList;
var $heading = $(this);
        }
var level;
 
// Определяем уровень
        // Перебираем все заголовки и элементы с классом .custom-heading
if ($heading.hasClass('custom-heading')) {
        $headings.each(function() {
level = 1;
            var $heading = $(this);
} else {
            var level;
// Проверяем наличие <span class="mw-headline"> внутри заголовка
 
var $headlineSpan = $heading.find('span.mw-headline');
            // Определяем уровень
if ($headlineSpan.length === 0) {
            if ($heading.hasClass('custom-heading')) {
return; // Пропускаем заголовок, если нет нужного <span>
                level = 1;
}
            } else {
// Определяем уровень заголовка по тегу
                // Проверяем наличие <span class="mw-headline"> внутри заголовка
var tagName = $heading.prop('tagName').toLowerCase();
                var $headlineSpan = $heading.find('span.mw-headline');
level = parseInt(tagName.charAt(1), 10);
                if ($headlineSpan.length === 0) {
}
                    return; // Пропускаем заголовок, если нет нужного <span>
updateCounters(level); // Обновляем счётчики для текущего уровня
                }
var sectionId = $heading.find('span.mw-headline').attr('id') || 'heading-' + getSectionNumber();
 
$heading.find('span.mw-headline').attr('id', sectionId); // Присваиваем уникальный id заголовку
                // Определяем уровень заголовка по тегу
// Извлекаем текст заголовка
                var tagName = $heading.prop('tagName').toLowerCase();
var headingText = $heading.find('span.mw-headline').text().trim() || $heading.text().trim();
                level = parseInt(tagName.charAt(1), 10);
// Проверяем, что текст заголовка не пустой
            }
if (headingText.length > 0) {
 
// Создание вложенных списков, если уровень больше 1
            updateCounters(level); // Обновляем счётчики для текущего уровня
if (level > 1) {
 
while (tocCounters.length > level) {
            var sectionId = $heading.find('span.mw-headline').attr('id') || 'heading-' + getSectionNumber();
$currentList = $currentList.parent(); // Переходим к родительскому <ul>
            $heading.find('span.mw-headline').attr('id', sectionId); // Присваиваем уникальный id заголовку
}
 
if ($currentList.children('ul').length === 0) {
            // Извлекаем текст заголовка
$currentList = createNestedList($currentList); // Создаём новый вложенный список
            var headingText = $heading.find('span.mw-headline').text().trim() || $heading.text().trim();
}
 
} else {
            // Проверяем, что текст заголовка не пустой
// Если уровень 1, сбрасываем вложенные списки
            if (headingText.length > 0) {
$currentList = $toc;
                // Создание вложенных списков, если уровень больше 1
}
                if (level > 1) {
// Создаём элемент списка в оглавлении (TOC)
                    while (tocCounters.length > level) {
var tocItem = $('<li>').addClass('toclevel-' + (level - 1)).append($('<a>').attr('href', '#' +
                        $currentList = $currentList.parent(); // Переходим к родительскому <ul>
sectionId).append($('<span>').addClass('tocnumber').text(getSectionNumber()), $('<span>').addClass(
                    }
'toctext').text(headingText)));
 
// Добавляем элемент в текущий список
                    if ($currentList.children('ul').length === 0) {
$currentList.append(tocItem);
                        $currentList = createNestedList($currentList); // Создаём новый вложенный список
}
                    }
});
                } else {
});
                    // Если уровень 1, сбрасываем вложенные списки
                    $currentList = $toc;
                }
 
                // Создаём элемент списка в оглавлении (TOC)
                var tocItem = $('<li>')
                    .addClass('toclevel-' + (level - 1))
                    .append(
                        $('<a>').attr('href', '#' + sectionId).append(
                            $('<span>').addClass('tocnumber').text(getSectionNumber()),
                            $('<span>').addClass('toctext').text(headingText)
                        )
                    );
 
                // Добавляем элемент в текущий список
                $currentList.append(tocItem);
            }
        });
    });
}
}
 
const currentPageTitle = document.title;
$(document).ready(function() {
$(document).ready(function() {
var serversStatus = document.querySelectorAll('.serversStatus');
var serversStatus = document.querySelectorAll('.serversStatus');
Строка 584: Строка 529:
}
}
}
}
const copyServerConnectionIcon = document.querySelectorAll(
const copyServerConnectionIcon = document.querySelectorAll('.copyServerConnectionIcon');
'.copyServerConnectionIcon');
copyServerConnectionIcon.forEach(function(icon) {
copyServerConnectionIcon.forEach(function(icon) {
icon.addEventListener('click', function() {
icon.addEventListener('click', function() {
Строка 606: Строка 550:
var tables = document.querySelectorAll('.wikitable');
var tables = document.querySelectorAll('.wikitable');
if (tables.length > 0) {
if (tables.length > 0) {
    setTimeout(function() {
setTimeout(function() {
        applyHighlighting();
applyHighlighting();
    }, 500);
}, 500);
}
}
var customHeadings = document.querySelectorAll('.custom-heading');
var customHeadings = document.querySelectorAll('.custom-heading');
if (customHeadings.length > 0) {
if (customHeadings.length > 0) {
    addHeadingsWithTOC();
addHeadingsWithTOC();
}
if (currentPageTitle.includes("Обсуждение_участницы:Kerisar")) {
var button = document.createElement("button");
button.innerText = "Создать архив";
document.getElementById("container").appendChild(button);
button.onclick = function() {
var apiUrl =
"https://station14.ru/api.php?action=parse&page=Шаблон:Бумажная работа/paperWork.json&prop=text&formatversion=2&format=json";
fetch(apiUrl).then(function(response) {
return response.json();
}).then(function(data) {
var text = data.parse.text;
// Извлекаем содержимое между [testarchivestart] и [testarchivestop]
var startTag = "[testarchivestart]";
var endTag = "[testarchivestop]";
var startIndex = text.indexOf(startTag);
var endIndex = text.indexOf(endTag);
if (startIndex !== -1 && endIndex !== -1) {
var extractedContent = text.substring(startIndex + startTag.length, endIndex);
// Преобразуем содержимое в base64
var base64Content = btoa(unescape(encodeURIComponent(extractedContent)));
// Создаем ссылку для скачивания
var link = document.createElement("a");
link.href = "data:application/octet-stream;base64," + base64Content;
link.download = "archive.txt"; // Имя файла для скачивания
link.innerText = "Скачать архив";
document.getElementById("container").appendChild(link);
} else {
alert("Теги [testarchivestart] и [testarchivestop] не найдены.");
}
}).catch(function(error) {
console.error("Ошибка:", error);
});
};
}
}
});
});
Строка 618: Строка 596:
if ($.inArray(mw.config.get('wgAction'), ['edit', 'submit']) !== -1) {
if ($.inArray(mw.config.get('wgAction'), ['edit', 'submit']) !== -1) {
mw.loader.load(
mw.loader.load(
'//ru.wikipedia.org/w/index.php?title=MediaWiki:Gadget-wikificator.js&action=raw&ctype=text/javascript'
'//ru.wikipedia.org/w/index.php?title=MediaWiki:Gadget-wikificator.js&action=raw&ctype=text/javascript');
);
}
}
var customizeToolbar = function() {
var customizeToolbar = function() {
Строка 682: Строка 659:
// Create button starting with hide text
// Create button starting with hide text
// Will be changed to the show text while calculating the maximum button size
// Will be changed to the show text while calculating the maximum button size
var $buttonTemplate = $('<span>').addClass(
var $buttonTemplate = $('<span>').addClass('mw-editsection-like load-page-button').append('[ ', $(
'mw-editsection-like load-page-button').append('[ ', $('<span>').addClass(
'<span>').addClass('jslink').text(i18n.hideText), ' ]');
'jslink').text(i18n.hideText), ' ]');
var extractList = function($contentContainer, listClass) {
var extractList = function($contentContainer, listClass) {
var $content = $contentContainer.find('.mw-parser-output > ul > li > ul')
var $content = $contentContainer.find('.mw-parser-output > ul > li > ul').children(
.children(':not(.nbttree-inherited)');
':not(.nbttree-inherited)');
if (listClass) {
if (listClass) {
$content.addClass(listClass);
$content.addClass(listClass);
Строка 717: Строка 693:
$heading.append($button);
$heading.append($button);
// Move the edit button to the right spot
// Move the edit button to the right spot
$contentContainer.find('.mw-editsection, .mw-editsection-like').insertAfter(
$contentContainer.find('.mw-editsection, .mw-editsection-like').insertAfter($button);
$button);
// Find max button width, and set its min-width to it
// Find max button width, and set its min-width to it
var hideWidth = $button.width();
var hideWidth = $button.width();
Строка 749: Строка 724:
$('.pageloader-contentloaded').each(function() {
$('.pageloader-contentloaded').each(function() {
var $fLoader = $(this);
var $fLoader = $(this);
if ($fLoader.data('page') === page && $fLoader.data(
if ($fLoader.data('page') === page && $fLoader.data('pageloader-content')) {
'pageloader-content')) {
$contentContainer.html($fLoader.data('pageloader-content')).removeClass('noscript');
$contentContainer.html($fLoader.data('pageloader-content')).removeClass(
'noscript');
mw.hook('wikipage.content').fire($contentContainer);
mw.hook('wikipage.content').fire($contentContainer);
if (treeview) {
if (treeview) {
Строка 773: Строка 746:
// $spinner will be false if the content somehow loaded before the module did
// $spinner will be false if the content somehow loaded before the module did
if ($spinner) {
if ($spinner) {
$spinner = $.createSpinner().addClass('mw-editsection-like').css(
$spinner = $.createSpinner().addClass('mw-editsection-like').css('min-width', $button.css(
'min-width', $button.css('min-width'));
'min-width'));
$button.hide().after($spinner);
$button.hide().after($spinner);
}
}
Строка 797: Строка 770:
var $link = $(this);
var $link = $(this);
if ($link.attr('href') === curPage) {
if ($link.attr('href') === curPage) {
$link.replaceWith($('<strong>').addClass('selflink').append(
$link.replaceWith($('<strong>').addClass('selflink').append($link.contents()));
$link.contents()));
}
}
});
});