MediaWiki:Common.js: различия между версиями
Pok (обсуждение | вклад) мНет описания правки |
Pok (обсуждение | вклад) мНет описания правки |
||
| Строка 339: | Строка 339: | ||
// Функция для подсветки ячеек в таблице при наведении | // Функция для подсветки ячеек в таблице при наведении | ||
function applyHighlighting() { | function applyHighlighting() { | ||
// Проверка, является ли устройство мобильным, если да — функция не выполняется | |||
if (/Mobi|Android/i.test(navigator.userAgent)) { | if (/Mobi|Android/i.test(navigator.userAgent)) { | ||
return; | return; | ||
} | } | ||
// Находим все таблицы с классом 'wikitable', кроме тех, что имеют класс 'no-highlight-table' | |||
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) { | Array.prototype.forEach.call(tables, function(table) { | ||
var tbody = table.querySelector('tbody'); | var tbody = table.querySelector('tbody'); | ||
| Строка 350: | Строка 353: | ||
var noHeader = table.classList.contains('no-header-table'); | var noHeader = table.classList.contains('no-header-table'); | ||
// Проверяем, что тело таблицы существует | |||
if (tbody) { | if (tbody) { | ||
// Получаем все строки <tr> внутри tbody, исключая строки, содержащие вложенные таблицы | |||
var rows = Array.prototype.slice.call(tbody.querySelectorAll('tr')).filter(function(row) { | var rows = Array.prototype.slice.call(tbody.querySelectorAll('tr')).filter(function(row) { | ||
return !row.querySelector('table'); | return !row.querySelector('table'); | ||
}); | }); | ||
// Пропускаем первую строку, если нет thead и нет класса 'no-header' | |||
var topLevelRows = (!thead && !noHeader) ? rows.slice(1) : rows; | var topLevelRows = (!thead && !noHeader) ? rows.slice(1) : rows; | ||
var hasInvalidRowspan = false; | |||
var hasTooManyRowspan = false; | |||
// Проходим по строкам первого уровня | |||
topLevelRows.forEach(function(row) { | |||
var cells = Array.prototype.slice.call(row.querySelectorAll('td, th')).filter(function(cell) { | |||
return !cell.classList.contains('mobile'); | |||
}); | |||
var cellCount = cells.length; | |||
// Проверяем, есть ли больше двух ячеек с атрибутом rowspan | |||
var rowspanCount = cells.filter(function(cell) { | |||
return cell.hasAttribute('rowspan') && cell.getAttribute('rowspan') !== '1'; | |||
}).length; | |||
// Если в строке больше двух ячеек с rowspan, функция не применяется | |||
if (rowspanCount > 2) { | |||
hasTooManyRowspan = true; | |||
return; | |||
} | |||
// Если строка имеет 3 или меньше ячеек и больше одного rowspan, не применяем функцию | |||
if (cellCount <= 3 && rowspanCount > 1) { | |||
hasTooManyRowspan = true; | |||
return; | |||
} | |||
// Проверяем, есть ли корректные ячейки с rowspan на краю строки (первый или последний элемент) | |||
var hasValidRowspanEdge = cells.some(function(cell, index) { | |||
return cell.hasAttribute('rowspan') && cell.getAttribute('rowspan') !== '1' && (index === 0 || index === cells.length - 1); | |||
}); | |||
// Если ячейки с rowspan находятся не на краю, устанавливаем флаг ошибки | |||
if (!hasValidRowspanEdge && cells.some(function(cell, index) { | |||
return cell.hasAttribute('rowspan') && cell.getAttribute('rowspan') !== '1' && index > 0 && index < cells.length - 1; | |||
})) { | |||
hasInvalidRowspan = true; | |||
} | |||
}); | |||
// Если есть некорректные строки с rowspan или слишком много rowspan, выходим | |||
if (hasTooManyRowspan || hasInvalidRowspan) return; | |||
var originalStyles = {}; | var originalStyles = {}; | ||
// | // Проходим по каждой строке для добавления событий подсветки | ||
topLevelRows.forEach(function(row, rowIndex) { | topLevelRows.forEach(function(row, rowIndex) { | ||
var cells = Array.prototype.slice.call(row.querySelectorAll('td, th')); | var cells = Array.prototype.slice.call(row.querySelectorAll('td, th')); | ||
// Сохраняем исходные стили каждой ячейки | |||
cells.forEach(function(cell, index) { | cells.forEach(function(cell, index) { | ||
if (!originalStyles[rowIndex]) originalStyles[rowIndex] = []; | if (!originalStyles[rowIndex]) originalStyles[rowIndex] = []; | ||
originalStyles[rowIndex][index] = { | originalStyles[rowIndex][index] = { | ||
| Строка 372: | Строка 419: | ||
color: getComputedStyle(cell).color | color: getComputedStyle(cell).color | ||
}; | }; | ||
}); | |||
cells.forEach(function(cell, index) { | |||
var rowspan = parseInt(cell.getAttribute('rowspan'), 10) || 1; | |||
// | // Добавляем обработчик события при наведении мыши | ||
cell.addEventListener('mouseover', function() { | cell.addEventListener('mouseover', function() { | ||
// | // Подсвечиваем все строки, охватываемые rowspan | ||
if (rowspan > 1) { | if (rowspan > 1) { | ||
for (var i = 0; i < rowspan; i++) { | for (var i = 0; i < rowspan; i++) { | ||
| Строка 391: | Строка 442: | ||
// Подсвечиваем ячейки в текущем ряду | // Подсвечиваем ячейки в текущем ряду | ||
cells.forEach(function(innerCell, innerIndex) { | cells.forEach(function(innerCell, innerIndex) { | ||
innerCell.style.backgroundColor = brightenColor( | innerCell.style.backgroundColor = brightenColor(getComputedStyle(innerCell).backgroundColor); | ||
innerCell.style.color = brightenColor( | innerCell.style.color = brightenColor(getComputedStyle(innerCell).color); | ||
}); | }); | ||
}); | }); | ||
// | // Добавляем обработчик события, когда мышь уходит с ячейки | ||
cell.addEventListener('mouseout', function() { | cell.addEventListener('mouseout', function() { | ||
// Восстанавливаем стили для всех строк, затронутых | // Восстанавливаем стили для всех строк, затронутых rowspan | ||
if (rowspan > 1) { | if (rowspan > 1) { | ||
for (var i = 0; i < rowspan; i++) { | for (var i = 0; i < rowspan; i++) { | ||