MediaWiki:Common.js: различия между версиями
Pok (обсуждение | вклад) Отмена правки 52022, сделанной 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'); | ||
| Строка 353: | Строка 352: | ||
var noHeader = table.classList.contains('no-header-table'); | var noHeader = table.classList.contains('no-header-table'); | ||
if (tbody) { | if (tbody) { | ||
// Получаем все строки <tr> внутри 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 hasInvalidRowspan = false; // Проверка наличия некорректного rowspan | ||
var hasTooManyRowspan = false; | var hasTooManyRowspan = false; // Проверка наличия слишком большого количества rowspan | ||
// Проверяем на наличие некорректных rowspan в таблице | |||
topLevelRows.forEach(function(row) { | topLevelRows.forEach(function(row) { | ||
var cells = Array.prototype.slice.call(row.querySelectorAll('td, th')).filter(function(cell) { | var cells = Array.prototype.slice.call(row.querySelectorAll('td, th')).filter(function(cell) { | ||
return !cell.classList.contains('mobile'); // Игнорируем ячейки с классом .mobile | |||
}); | }); | ||
var cellCount = cells.length; | var cellCount = cells.length; | ||
var rowspanCount = cells.filter(function(cell) { | var rowspanCount = cells.filter(function(cell) { | ||
return cell.hasAttribute('rowspan') && cell.getAttribute('rowspan') !== '1'; | return cell.hasAttribute('rowspan') && cell.getAttribute('rowspan') !== '1'; | ||
}).length; | }).length; | ||
// | // Слишком много rowspan в одной строке | ||
if (rowspanCount > 2) { | if (rowspanCount > 2) { | ||
hasTooManyRowspan = true; | hasTooManyRowspan = true; | ||
| Строка 385: | Строка 380: | ||
} | } | ||
// | // Слишком много rowspan в строке с небольшим количеством ячеек | ||
if (cellCount <= 3 && rowspanCount > 1) { | if (cellCount <= 3 && rowspanCount > 1) { | ||
hasTooManyRowspan = true; | hasTooManyRowspan = true; | ||
| Строка 391: | Строка 386: | ||
} | } | ||
// | // Проверка на наличие rowspan на краях строки | ||
var 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); | ||
}); | }); | ||
// | // Некорректное использование rowspan в середине строки | ||
if (!hasValidRowspanEdge && cells.some(function(cell, index) { | if (!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; | ||
| Строка 404: | Строка 399: | ||
}); | }); | ||
// | // Прерываем выполнение, если найдены некорректные rowspan | ||
if (hasTooManyRowspan || hasInvalidRowspan) return; | if (hasTooManyRowspan || hasInvalidRowspan) return; | ||
// | // Обрабатываем каждую строку таблицы | ||
topLevelRows.forEach(function(row) { | topLevelRows.forEach(function(row) { | ||
var cells = Array.prototype.slice.call(row.querySelectorAll('td, th')); | var cells = Array.prototype.slice.call(row.querySelectorAll('td, th')); | ||
var originalStyles = cells.map(function(cell) { | var originalStyles = cells.map(function(cell) { | ||
return { | return { | ||
backgroundColor: getComputedStyle(cell).backgroundColor, | backgroundColor: getComputedStyle(cell).backgroundColor, | ||
| Строка 418: | Строка 412: | ||
}); | }); | ||
// Добавляем | // Добавляем обработчики для каждой ячейки | ||
cells.forEach(function(cell, index) { | 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) { | |||
for (var i = 0; i < rowspan; i++) { | |||
var targetRow = topLevelRows[topLevelRows.indexOf(row) + i]; | |||
if (targetRow) { | |||
var targetCells = targetRow.querySelectorAll('td, th'); | |||
Array.prototype.forEach.call(targetCells, function(innerCell) { | |||
innerCell.style.backgroundColor = brightenColor(getComputedStyle(innerCell).backgroundColor); | |||
innerCell.style.color = brightenColor(getComputedStyle(innerCell).color); | |||
}); | |||
} | |||
} | |||
} | |||
// Подсвечиваем ячейки в текущем ряду | |||
cells.forEach(function(innerCell, innerIndex) { | cells.forEach(function(innerCell, innerIndex) { | ||
innerCell.style.backgroundColor = brightenColor(originalStyles[innerIndex].backgroundColor); | |||
innerCell.style.color = brightenColor(originalStyles[innerIndex].color); | |||
}); | }); | ||
}); | }); | ||
// | // Обработчик при убирании курсора с ячейки | ||
cell.addEventListener('mouseout', function() { | cell.addEventListener('mouseout', function() { | ||
// Восстанавливаем стили для всех строк, затронутых `rowspan` | |||
if (rowspan > 1) { | |||
for (var i = 0; i < rowspan; i++) { | |||
var targetRow = topLevelRows[topLevelRows.indexOf(row) + i]; | |||
if (targetRow) { | |||
var targetCells = targetRow.querySelectorAll('td, th'); | |||
Array.prototype.forEach.call(targetCells, function(innerCell) { | |||
innerCell.style.backgroundColor = getComputedStyle(innerCell).backgroundColor; | |||
innerCell.style.color = getComputedStyle(innerCell).color; | |||
}); | |||
} | |||
} | |||
} | |||
// Восстанавливаем стили в текущем ряду | |||
cells.forEach(function(innerCell, innerIndex) { | cells.forEach(function(innerCell, innerIndex) { | ||
innerCell.style.backgroundColor = originalStyles[innerIndex].backgroundColor; | |||
innerCell.style.color = originalStyles[innerIndex].color; | |||
}); | }); | ||
}); | }); | ||