Есть скрипт (знаю, что не профессиональный), уже замучался с регулярками.
Скрытый текст
Код:
document.addEventListener("DOMContentLoaded", function() {
document.querySelectorAll("td.e").forEach(function (cell) {
cell.innerHTML = cell.innerHTML.replace(/_/g, "_<wbr>");
});
// ---------------------------------
// Замена логотипа
const oldLogo = document.querySelector('img[src*="data:image/png;base64,"]');
if (oldLogo) {
const newLogo = document.createElement('img');
newLogo.src = '/res/imgs/phplogo.svg';
newLogo.alt = 'PHP Logo';
newLogo.className = 'custom-logo';
newLogo.style.width = '15vw';
newLogo.style.height = 'auto';
const parent = oldLogo.parentElement;
if (parent.tagName.toLowerCase() === 'a') {
parent.replaceChild(newLogo, oldLogo);
// Проверяем, есть ли уже ссылка, если нет — добавляем
if (!parent.nextElementSibling || !parent.nextElementSibling.classList.contains('logo-text')) {
const textLink = document.createElement('a');
textLink.href = 'https://github.com/BlagoYar/beautiful_phpinfo';
textLink.textContent = 'Designed by BlagoYar';
textLink.className = 'logo-text';
textLink.target = '_blank'; // Открывать в новой вкладке
textLink.rel = 'noopener noreferrer';
parent.parentElement.insertBefore(textLink, parent.nextSibling);
}
}
}
// ---------------------------------
// Замена слова active
function replaceActiveText() {
const elements = document.querySelectorAll('td.v');
elements.forEach(element => {
if (element.textContent.trim() === 'active') {
const span = document.createElement('span');
span.classList.add('enabled-text');
span.textContent = 'active';
// Заменяем текстовый узел внутри td на span
element.innerHTML = ''; // Очищаем содержимое td
element.appendChild(span); // Добавляем span внутрь td
}
});
}
// Запускаем функцию после загрузки DOM
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', replaceActiveText);
} else {
replaceActiveText(); // DOMContentLoaded уже сработал
}
function replaceFontWithClass() {
const fontElements = document.querySelectorAll('font[style*="color: #"]');
fontElements.forEach(element => {
const style = element.getAttribute('style');
const colorCode = style.match(/color: (#[\da-fA-F]{3,6})/)[1];
const colorName = getColorName(colorCode); // Получаем английское название цвета
const className = `${colorName}-${colorCode.replace('#', '')}`; // Формируем имя класса
element.classList.add(className);
element.removeAttribute('style');
// Создаем CSS правило
const styleElement = document.createElement('style');
styleElement.textContent = `.${className} { color: ${colorCode} !important; }`;
document.head.appendChild(styleElement);
});
}
function getColorName(hexColor) {
// Здесь можно добавить более сложную логику для преобразования hex в название цвета.
// Пока что, для простоты, будем возвращать просто "color"
return "color"; // В дальнейшем можно улучшить
}
// Запускаем функцию после загрузки DOM
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', replaceFontWithClass);
} else {
replaceFontWithClass(); // DOMContentLoaded уже сработал
}
// ---------------------------------
// Замена 0 и 1
const numberMappings = {
"0": "disabled-int",
"1": "enabled-int"
};
function replaceNumbersWithSpan(node) {
const text = node.textContent;
const regex = new RegExp(`(?:^|\\s)\\b(${Object.keys(numberMappings).join('|')})\\b(?:$|\\s)`, 'g');
const newContent = text.replace(regex, (match, p1) => {
const span = document.createElement('span');
span.className = numberMappings[p1];
span.textContent = p1;
return span.outerHTML;
});
const parentNode = node.parentNode;
const tempDiv = document.createElement('div');
tempDiv.innerHTML = newContent;
while (tempDiv.firstChild) {
parentNode.insertBefore(tempDiv.firstChild, node);
}
parentNode.removeChild(node);
}
function traverseNodesForNumbers(node) {
node.childNodes.forEach(child => {
if (child.nodeType === Node.ELEMENT_NODE) {
traverseNodesForNumbers(child);
} else if (child.nodeType === Node.TEXT_NODE) {
replaceNumbersWithSpan(child);
}
});
}
traverseNodesForNumbers(document.body);
// ---------------------------------
// Замена слов
const wordMappings = {
"enabled": "enabled-text",
"Enabled": "enabled-text",
"disabled": "disabled-text",
"Disabled": "disabled-text",
"Off": "disabled-text",
"On": "enabled-text",
"no value": "no-text",
"available": "available-text"
};
function replaceWordsWithSpan(node) {
const text = node.textContent;
// Улучшенное регулярное выражение:
const regex = new RegExp(`\\b(?:enabled|Enabled|disabled|Disabled|Off|On|no value|available)\\b`, 'gi');
const newContent = text.replace(regex, match => {
const span = document.createElement('span');
span.className = wordMappings[match];
span.textContent = match;
return span.outerHTML;
});
const parentNode = node.parentNode;
const tempDiv = document.createElement('div');
tempDiv.innerHTML = newContent;
while (tempDiv.firstChild) {
parentNode.insertBefore(tempDiv.firstChild, node);
}
parentNode.removeChild(node);
}
function traverseNodesForWords(node) {
node.childNodes.forEach(child => {
if (child.nodeType === Node.ELEMENT_NODE) {
if (child.tagName !== 'TH') {
traverseNodesForWords(child);
}
} else if (child.nodeType === Node.TEXT_NODE) {
replaceWordsWithSpan(child);
}
});
}
traverseNodesForWords(document.body);
document.querySelectorAll("td.v").forEach(el => {
el.childNodes.forEach(node => {
if (node.nodeType === Node.TEXT_NODE) {
node.textContent = node.textContent.replace(/\bno\b/g, 'no');
}
});
el.innerHTML = el.innerHTML.replace(/\bno\b(?!-)/g, '<span class="no-text">no</span>');
});
const scrollButtonsContainer = document.createElement("div");
scrollButtonsContainer.classList.add("scroll-buttons");
document.body.appendChild(scrollButtonsContainer);
const buttonsData = [
{ symbol: "⬆", action: () => window.scrollTo({ top: 0, behavior: 'smooth' }) },
{ symbol: "⚪", action: () => window.scrollTo({ top: document.body.scrollHeight / 2, behavior: 'smooth' }) },
{ symbol: "⬇", action: () => window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' }) }
];
buttonsData.forEach(({ symbol, action }) => {
const btn = document.createElement("button");
btn.classList.add("scroll-btn");
btn.textContent = symbol;
btn.addEventListener("click", action);
scrollButtonsContainer.appendChild(btn);
});
function updateButtonPosition() {
const mainContent = document.querySelector(".center");
if (mainContent) {
const marginBottom = parseFloat(getComputedStyle(mainContent).marginBottom);
scrollButtonsContainer.style.bottom = `${marginBottom + 20}px`;
}
}
let scrollTimeout;
let firstScroll = false;
function updateButtonsVisibility() {
if (!firstScroll && window.scrollY > 50) {
firstScroll = true;
scrollButtonsContainer.classList.add("visible");
}
if (firstScroll) {
scrollButtonsContainer.classList.add("visible");
clearTimeout(scrollTimeout);
scrollTimeout = setTimeout(() => {
if (!scrollButtonsContainer.matches(":hover")) {
scrollButtonsContainer.classList.remove("visible");
}
}, 2000);
}
}
window.addEventListener("scroll", () => {
updateButtonsVisibility();
updateButtonPosition();
});
window.addEventListener("resize", updateButtonPosition);
scrollButtonsContainer.addEventListener("mouseenter", () => clearTimeout(scrollTimeout));
scrollButtonsContainer.addEventListener("mouseleave", () => {
scrollTimeout = setTimeout(() => scrollButtonsContainer.classList.remove("visible"), 2000);
});
// Убеждаемся, что кнопки скрыты при загрузке
scrollButtonsContainer.style.display = "none";
// Показываем контейнер только после первой прокрутки
window.addEventListener("scroll", function firstScrollCheck() {
if (window.scrollY > 50) {
scrollButtonsContainer.style.display = "flex";
scrollButtonsContainer.classList.add("visible");
window.removeEventListener("scroll", firstScrollCheck);
}
});
updateButtonPosition();
});
Всё нужно заменить с учётом, чтобы последующее оформление стилями не затронуло, если эти значения есть где-то в контексте с другими, например "0" встречается в "1.0.25" или "active" в "Previously active authors, editors ..."
Есть несколько ячеек с кодами цветов, нужно каждый под свой цвет/код, пример
<font style="color: [здесь код цвета в формате #FF8000]">#FF8000</font> -> <font class="color-[тот же код цвета в формате #FF8000]">#FF8000</font>
<td class="v">available, disabled </td>
-> <td class="v"><span class="v available-text">available</span>,<span class="v disabled-text">disabled </span></td>
<td class="v">active </td>
-> <td class="v enabled-text">active </td>
<td class="v">1</td> -> <td class="v enabled-text">1</td>
<td class="v">enabled </td>
-> <td class="v enabled-text">enabled </td>
<td class="v">Enabled </td>
-> <td class="v enabled-text">Enabled </td>
<td class="v">On</td>
-> <td class="v enabled-text">On</td>
<td class="v">0</td>
-> <td class="v disabled-text">0</td>
<td class="v">disabled </td>
-> <td class="v disabled-text">disabled </td>
<td class="v">Disabled </td>
-> <td class="v disabled-text">Disabled </td>
<td class="v">disabled (install ext/bz2) </td>
-><td class="v"><span class="disabled-text">disabled </span> (install ext/bz2)</td>
<td class="v">Off</td>
-> <td class="v disabled-text">Off</td>
<td class="v">no </td>
-> <td class="v no-text">no </td>
<td class="v">no-ctrl</td>
-> <td class="v no-text">no-ctrl</td>
<td class="v">nocache</td>
-> <td class="v no-text">nocache</td>
<td class="v">no value </td>
-> <td class="v no-text">no value </td>
Сейчас работает, но кривовато, где-то enabled в неположенном месте (session_on_enabled), в консоли браузера "[Violation]Forced reflow while executing JavaScript took 46ms"
ПС. Если кому интересно
ссылка на проект