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

мНет описания правки
мНет описания правки
Строка 339: Строка 339:
// Функция для подсветки ячеек в таблице при наведении
// Функция для подсветки ячеек в таблице при наведении
function applyHighlighting() {
function applyHighlighting() {
     // Проверка, является ли устройство мобильным, если да — функция не выполняется
     // Проверка, является ли устройство мобильным
     if (/Mobi|Android/i.test(navigator.userAgent)) {
     if (/Mobi|Android/i.test(navigator.userAgent)) {
         return;
         return;
Строка 353: Строка 353:
         var noHeader = table.classList.contains('no-header-table');
         var noHeader = table.classList.contains('no-header-table');


        // Проверяем, что тело таблицы существует
         if (!tbody) return;
         if (tbody) {
            // Получаем все строки <tr> внутри tbody, исключая строки, содержащие вложенные таблицы
            var rows = Array.prototype.slice.call(tbody.querySelectorAll('tr')).filter(function(row) {
                return !row.querySelector('table');
            });


            // Пропускаем первую строку, если нет thead и нет класса 'no-header'
        // Получаем все строки <tr> внутри tbody, исключая строки с вложенными таблицами
             var topLevelRows = (!thead && !noHeader) ? rows.slice(1) : rows;
        var rows = Array.prototype.slice.call(tbody.querySelectorAll('tr')).filter(function(row) {
             return !row.querySelector('table');
        });


            var hasInvalidRowspan = false;
        // Пропускаем первую строку, если нет thead и нет класса 'no-header'
            var hasTooManyRowspan = false;
        var topLevelRows = (!thead && !noHeader) ? rows.slice(1) : rows;


            // Проходим по строкам первого уровня
        var hasInvalidRowspan = false;
            topLevelRows.forEach(function(row) {
        var hasTooManyRowspan = false;
                var cells = Array.prototype.slice.call(row.querySelectorAll('td, th')).filter(function(cell) {
                    return !cell.classList.contains('mobile');
                });
                var cellCount = cells.length;


                // Проверяем, есть ли больше двух ячеек с атрибутом rowspan
        // Проходим по строкам первого уровня для проверки корректности rowspan
                var rowspanCount = cells.filter(function(cell) {
        topLevelRows.forEach(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');
            });
            var cellCount = cells.length;


                // Если в строке больше двух ячеек с rowspan, функция не применяется
            // Проверка на наличие ячеек с rowspan
                if (rowspanCount > 2) {
            var rowspanCount = cells.filter(function(cell) {
                    hasTooManyRowspan = true;
                return cell.hasAttribute('rowspan') && cell.getAttribute('rowspan') !== '1';
                    return;
            }).length;
                }


                // Если строка имеет 3 или меньше ячеек и больше одного rowspan, не применяем функцию
            if (rowspanCount > 2) {
                if (cellCount <= 3 && rowspanCount > 1) {
                hasTooManyRowspan = true;
                    hasTooManyRowspan = true;
                return;
                    return;
            }
                }


                // Проверяем, есть ли корректные ячейки с rowspan на краю строки (первый или последний элемент)
            if (cellCount <= 3 && rowspanCount > 1) {
                 var hasValidRowspanEdge = cells.some(function(cell, index) {
                 hasTooManyRowspan = true;
                    return cell.hasAttribute('rowspan') && cell.getAttribute('rowspan') !== '1' && (index === 0 || index === cells.length - 1);
                return;
                });
            }


                // Если ячейки с rowspan находятся не на краю, устанавливаем флаг ошибки
            // Проверка корректности rowspan на краю строки
                if (!hasValidRowspanEdge && cells.some(function(cell, index) {
            var hasValidRowspanEdge = cells.some(function(cell, index) {
                    return cell.hasAttribute('rowspan') && cell.getAttribute('rowspan') !== '1' && index > 0 && index < cells.length - 1;
                return cell.hasAttribute('rowspan') && cell.getAttribute('rowspan') !== '1' && (index === 0 || index === cells.length - 1);
                })) {
                    hasInvalidRowspan = true;
                }
             });
             });


             // Если есть некорректные строки с rowspan или слишком много rowspan, выходим
             if (!hasValidRowspanEdge && cells.some(function(cell, index) {
             if (hasTooManyRowspan || hasInvalidRowspan) return;
                return cell.hasAttribute('rowspan') && cell.getAttribute('rowspan') !== '1' && index > 0 && index < cells.length - 1;
             })) {
                hasInvalidRowspan = true;
            }
        });


            var originalStyles = {};
        // Если некорректные строки с rowspan или слишком много rowspan — игнорируем таблицу
        if (hasTooManyRowspan || hasInvalidRowspan) return;


            // Проходим по каждой строке для добавления событий подсветки
        // Объект для хранения оригинальных стилей
            topLevelRows.forEach(function(row, rowIndex) {
        var originalStyles = {};
                var cells = Array.prototype.slice.call(row.querySelectorAll('td, th'));


                // Сохраняем исходные стили каждой ячейки
        // Проходим по каждой строке для добавления событий подсветки
                cells.forEach(function(cell, index) {
        topLevelRows.forEach(function(row, rowIndex) {
                    if (!originalStyles[rowIndex]) originalStyles[rowIndex] = [];
            var cells = Array.prototype.slice.call(row.querySelectorAll('td, th'));
                    originalStyles[rowIndex][index] = {
 
                        backgroundColor: getComputedStyle(cell).backgroundColor,
            // Сохраняем исходные стили каждой ячейки
                        color: getComputedStyle(cell).color
            originalStyles[rowIndex] = {};
                    };
            cells.forEach(function(cell, cellIndex) {
                });
                originalStyles[rowIndex][cellIndex] = {
                    backgroundColor: getComputedStyle(cell).backgroundColor,
                    color: getComputedStyle(cell).color
                };
            });


                cells.forEach(function(cell, index) {
            cells.forEach(function(cell, cellIndex) {
                    var rowspan = parseInt(cell.getAttribute('rowspan'), 10) || 1;
                var rowspan = parseInt(cell.getAttribute('rowspan'), 10) || 1;


                    // Добавляем обработчик события при наведении мыши
                // Добавляем обработчик события при наведении мыши
                    cell.addEventListener('mouseover', function() {
                cell.addEventListener('mouseover', function() {
                        // Подсвечиваем все строки, охватываемые rowspan
                    // Подсвечиваем все строки, охватываемые rowspan
                        if (rowspan > 1) {
                    for (var i = rowIndex; i < rowIndex + rowspan; i++) {
                            for (var i = 0; i < rowspan; i++) {
                        var targetRow = topLevelRows[i];
                                var targetRow = topLevelRows[rowIndex + i];
                        if (!targetRow) continue;
                                if (targetRow) {
                                    var targetCells = targetRow.querySelectorAll('td, th');
                                    Array.prototype.forEach.call(targetCells, function(innerCell, innerIndex) {
                                        innerCell.style.backgroundColor = brightenColor(getComputedStyle(innerCell).backgroundColor);
                                        innerCell.style.color = brightenColor(getComputedStyle(innerCell).color);
                                    });
                                }
                            }
                        }


                         // Подсвечиваем ячейки в текущем ряду
                         var targetCells = Array.prototype.slice.call(targetRow.querySelectorAll('td, th'));
                         cells.forEach(function(innerCell, innerIndex) {
                         targetCells.forEach(function(targetCell, targetIndex) {
                             innerCell.style.backgroundColor = brightenColor(getComputedStyle(innerCell).backgroundColor);
                             targetCell.style.backgroundColor = brightenColor(getComputedStyle(targetCell).backgroundColor);
                             innerCell.style.color = brightenColor(getComputedStyle(innerCell).color);
                             targetCell.style.color = brightenColor(getComputedStyle(targetCell).color);
                         });
                         });
                    }


                        // Подсвечиваем ячейки, прилегающие к rowspan
                    // Подсвечиваем ячейки в текущем ряду
                        if (rowspan > 1) {
                    cells.forEach(function(innerCell, innerIndex) {
                            var nextRow = topLevelRows[rowIndex + rowspan];
                        innerCell.style.backgroundColor = brightenColor(getComputedStyle(innerCell).backgroundColor);
                            if (nextRow) {
                        innerCell.style.color = brightenColor(getComputedStyle(innerCell).color);
                                var nextRowCells = Array.prototype.slice.call(nextRow.querySelectorAll('td, th'));
                                nextRowCells.forEach(function(nextCell) {
                                    if (nextCell.cellIndex >= cell.cellIndex && nextCell.cellIndex < cell.cellIndex + rowspan) {
                                        nextCell.style.backgroundColor = brightenColor(getComputedStyle(nextCell).backgroundColor);
                                        nextCell.style.color = brightenColor(getComputedStyle(nextCell).color);
                                    }
                                });
                            }
                        }
                     });
                     });


                     // Добавляем обработчик события, когда мышь уходит с ячейки
                     // Подсвечиваем ячейки, прилегающие к текущей ячейке с rowspan
                     cell.addEventListener('mouseout', function() {
                     for (var i = rowIndex + 1; i < rowIndex + rowspan; i++) {
                        // Восстанавливаем стили для всех строк, затронутых rowspan
                        if (!topLevelRows[i]) continue;
                        if (rowspan > 1) {
                            for (var i = 0; i < rowspan; i++) {
                                var targetRow = topLevelRows[rowIndex + i];
                                if (targetRow) {
                                    var targetCells = targetRow.querySelectorAll('td, th');
                                    Array.prototype.forEach.call(targetCells, function(innerCell, innerIndex) {
                                        innerCell.style.backgroundColor = originalStyles[rowIndex + i][innerIndex].backgroundColor;
                                        innerCell.style.color = originalStyles[rowIndex + i][innerIndex].color;
                                    });
                                }
                            }
                        }


                         // Восстанавливаем стили в текущем ряду
                         var affectedRow = topLevelRows[i];
                         cells.forEach(function(innerCell, innerIndex) {
                        var affectedCells = Array.prototype.slice.call(affectedRow.querySelectorAll('td, th'));
                             innerCell.style.backgroundColor = originalStyles[rowIndex][innerIndex].backgroundColor;
 
                             innerCell.style.color = originalStyles[rowIndex][innerIndex].color;
                        affectedCells.forEach(function(affectedCell) {
                            affectedCell.style.backgroundColor = brightenColor(getComputedStyle(affectedCell).backgroundColor);
                            affectedCell.style.color = brightenColor(getComputedStyle(affectedCell).color);
                        });
                    }
                });
 
                // Добавляем обработчик события, когда мышь уходит с ячейки
                cell.addEventListener('mouseout', function() {
                    // Восстанавливаем стили для всех строк, затронутых rowspan
                    for (var i = rowIndex; i < rowIndex + rowspan; i++) {
                        var targetRow = topLevelRows[i];
                        if (!targetRow) continue;
 
                        var targetCells = Array.prototype.slice.call(targetRow.querySelectorAll('td, th'));
                         targetCells.forEach(function(targetCell, targetIndex) {
                             targetCell.style.backgroundColor = originalStyles[i][targetIndex].backgroundColor;
                             targetCell.style.color = originalStyles[i][targetIndex].color;
                         });
                         });
                    }
                    // Восстанавливаем стили в текущем ряду
                    cells.forEach(function(innerCell, innerIndex) {
                        innerCell.style.backgroundColor = originalStyles[rowIndex][innerIndex].backgroundColor;
                        innerCell.style.color = originalStyles[rowIndex][innerIndex].color;
                     });
                     });
                 });
                 });
             });
             });
         }
         });
     });
     });
}
}