Исправлена проблема с лишними пустыми строками в Single View и Multi View
- Радикально переработаны функции очистки пустых строк - Удалены переносы строк из HTML-шаблонов логов - Добавлены CSS стили для правильного отображения элементов .line - Увеличена частота периодической очистки до 2 секунд - Добавлена агрессивная очистка во всех ключевых точках приложения - Улучшена логика определения типа элемента для правильной очистки Автор: Сергей Антропов Сайт: https://devops.org.ru
This commit is contained in:
parent
012c31522c
commit
59e0810750
@ -1098,9 +1098,9 @@ main{display:none}
|
|||||||
.counter{font-size:11px;color:var(--muted)}
|
.counter{font-size:11px;color:var(--muted)}
|
||||||
.logwrap{flex:1;overflow:auto;padding:10px}
|
.logwrap{flex:1;overflow:auto;padding:10px}
|
||||||
.log{white-space:pre-wrap;word-break:break-word;font-size:12px;line-height:1.5;margin:0;tab-size:2}
|
.log{white-space:pre-wrap;word-break:break-word;font-size:12px;line-height:1.5;margin:0;tab-size:2}
|
||||||
.line{color:var(--fg)} .ok{color:var(--ok)} .warn{color:var(--warn)} .err{color:var(--err)} .dbg{color:#7dcfff} .ts{color:var(--muted)}
|
.line{color:var(--fg); display:block; margin:0; padding:0; line-height:1.4} .ok{color:var(--ok)} .warn{color:var(--warn)} .err{color:var(--err)} .dbg{color:#7dcfff} .ts{color:var(--muted)}
|
||||||
/* Цвета для multi-view логов */
|
/* Цвета для multi-view логов */
|
||||||
.multi-view-log .line{color:var(--fg) !important}
|
.multi-view-log .line{color:var(--fg) !important; display:block; margin:0; padding:0; line-height:1.4}
|
||||||
.multi-view-log .ok{color:var(--ok) !important}
|
.multi-view-log .ok{color:var(--ok) !important}
|
||||||
.multi-view-log .warn{color:var(--warn) !important}
|
.multi-view-log .warn{color:var(--warn) !important}
|
||||||
.multi-view-log .err{color:var(--err) !important}
|
.multi-view-log .err{color:var(--err) !important}
|
||||||
@ -1108,7 +1108,7 @@ main{display:none}
|
|||||||
.multi-view-log .ts{color:var(--muted) !important}
|
.multi-view-log .ts{color:var(--muted) !important}
|
||||||
|
|
||||||
/* Дополнительные стили для multi-view логов */
|
/* Дополнительные стили для multi-view логов */
|
||||||
.multi-view-log span.line{color:var(--fg) !important}
|
.multi-view-log span.line{color:var(--fg) !important; display:block; margin:0; padding:0; line-height:1.4}
|
||||||
.multi-view-log span.ok{color:var(--ok) !important}
|
.multi-view-log span.ok{color:var(--ok) !important}
|
||||||
.multi-view-log span.warn{color:var(--warn) !important}
|
.multi-view-log span.warn{color:var(--warn) !important}
|
||||||
.multi-view-log span.err{color:var(--err) !important}
|
.multi-view-log span.err{color:var(--err) !important}
|
||||||
@ -1434,18 +1434,18 @@ function refreshAllLogs() {
|
|||||||
// Обновляем отображение
|
// Обновляем отображение
|
||||||
obj.logEl.innerHTML = filteredHtml.join('');
|
obj.logEl.innerHTML = filteredHtml.join('');
|
||||||
|
|
||||||
|
// Сразу очищаем пустые строки в legacy панели
|
||||||
|
cleanSingleViewEmptyLines(obj.logEl);
|
||||||
|
cleanDuplicateLines(obj.logEl);
|
||||||
|
|
||||||
// Обновляем современный интерфейс
|
// Обновляем современный интерфейс
|
||||||
if (state.current && state.current.id === id && els.logContent) {
|
if (state.current && state.current.id === id && els.logContent) {
|
||||||
els.logContent.innerHTML = obj.logEl.innerHTML;
|
els.logContent.innerHTML = obj.logEl.innerHTML;
|
||||||
|
|
||||||
// Очищаем дублированные строки в Single View после обновления
|
// Очищаем дублированные строки в Single View после обновления
|
||||||
cleanDuplicateLines(els.logContent);
|
|
||||||
cleanSingleViewEmptyLines(els.logContent);
|
cleanSingleViewEmptyLines(els.logContent);
|
||||||
|
cleanDuplicateLines(els.logContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Очищаем дублированные строки в legacy панели
|
|
||||||
cleanDuplicateLines(obj.logEl);
|
|
||||||
cleanSingleViewEmptyLines(obj.logEl);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Обновляем мультипросмотр
|
// Обновляем мультипросмотр
|
||||||
@ -1473,7 +1473,8 @@ function refreshAllLogs() {
|
|||||||
if (multiViewLog) {
|
if (multiViewLog) {
|
||||||
multiViewLog.innerHTML = filteredHtml.join('');
|
multiViewLog.innerHTML = filteredHtml.join('');
|
||||||
|
|
||||||
// Очищаем дублированные строки после обновления
|
// Сразу очищаем пустые строки в мультипросмотре
|
||||||
|
cleanMultiViewEmptyLines(multiViewLog);
|
||||||
cleanMultiViewDuplicateLines(multiViewLog);
|
cleanMultiViewDuplicateLines(multiViewLog);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -2566,25 +2567,26 @@ function processMultiViewLineBreaks(text) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Функция для очистки пустых строк в multi view
|
* Функция для радикальной очистки пустых строк в multi view
|
||||||
* Удаляет пустые строки между "Connected" и началом логов
|
* Удаляет все пустые строки и лишние переносы строк
|
||||||
* @param {HTMLElement} multiViewLog - элемент лога multi view
|
* @param {HTMLElement} multiViewLog - элемент лога multi view
|
||||||
*/
|
*/
|
||||||
function cleanMultiViewEmptyLines(multiViewLog) {
|
function cleanMultiViewEmptyLines(multiViewLog) {
|
||||||
if (!multiViewLog) return;
|
if (!multiViewLog) return;
|
||||||
|
|
||||||
// Находим все строки в логе
|
let removedCount = 0;
|
||||||
const lines = Array.from(multiViewLog.querySelectorAll('.line'));
|
|
||||||
|
|
||||||
// Удаляем пустые строки (строки без текста или только с пробелами)
|
// Удаляем все пустые строки (элементы .line без текста)
|
||||||
|
const lines = Array.from(multiViewLog.querySelectorAll('.line'));
|
||||||
lines.forEach(line => {
|
lines.forEach(line => {
|
||||||
const textContent = line.textContent || line.innerText || '';
|
const textContent = line.textContent || line.innerText || '';
|
||||||
if (textContent.trim() === '') {
|
if (textContent.trim() === '') {
|
||||||
line.remove();
|
line.remove();
|
||||||
|
removedCount++;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Также удаляем пустые текстовые узлы
|
// Удаляем все текстовые узлы, которые содержат только пробелы и переносы строк
|
||||||
const walker = document.createTreeWalker(
|
const walker = document.createTreeWalker(
|
||||||
multiViewLog,
|
multiViewLog,
|
||||||
NodeFilter.SHOW_TEXT,
|
NodeFilter.SHOW_TEXT,
|
||||||
@ -2595,12 +2597,27 @@ function cleanMultiViewEmptyLines(multiViewLog) {
|
|||||||
const textNodesToRemove = [];
|
const textNodesToRemove = [];
|
||||||
let node;
|
let node;
|
||||||
while (node = walker.nextNode()) {
|
while (node = walker.nextNode()) {
|
||||||
if (node.textContent.trim() === '') {
|
const content = node.textContent;
|
||||||
|
// Удаляем все узлы, которые содержат только пробелы, переносы строк или табуляцию
|
||||||
|
if (content.trim() === '') {
|
||||||
textNodesToRemove.push(node);
|
textNodesToRemove.push(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
textNodesToRemove.forEach(node => node.remove());
|
textNodesToRemove.forEach(node => node.remove());
|
||||||
|
|
||||||
|
// Удаляем все пустые текстовые узлы между элементами .line
|
||||||
|
const allNodes = Array.from(multiViewLog.childNodes);
|
||||||
|
for (let i = allNodes.length - 1; i >= 0; i--) {
|
||||||
|
const node = allNodes[i];
|
||||||
|
if (node.nodeType === Node.TEXT_NODE && node.textContent.trim() === '') {
|
||||||
|
node.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (removedCount > 0) {
|
||||||
|
console.log(`cleanMultiViewEmptyLines: Удалено ${removedCount} пустых строк`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2623,7 +2640,8 @@ function cleanMultiViewDuplicateLines(multiViewLog) {
|
|||||||
const currentText = currentLine.textContent || currentLine.innerText || '';
|
const currentText = currentLine.textContent || currentLine.innerText || '';
|
||||||
const previousText = previousLine.textContent || previousLine.innerText || '';
|
const previousText = previousLine.textContent || previousLine.innerText || '';
|
||||||
|
|
||||||
if (currentText.trim() === previousText.trim() && currentText.trim() !== '') {
|
// Удаляем дублированные строки (включая пустые)
|
||||||
|
if (currentText.trim() === previousText.trim()) {
|
||||||
console.log(`cleanMultiViewDuplicateLines: Удаляем дублированную строку: ${currentText.substring(0, 50)}...`);
|
console.log(`cleanMultiViewDuplicateLines: Удаляем дублированную строку: ${currentText.substring(0, 50)}...`);
|
||||||
currentLine.remove();
|
currentLine.remove();
|
||||||
removedCount++;
|
removedCount++;
|
||||||
@ -2631,6 +2649,9 @@ function cleanMultiViewDuplicateLines(multiViewLog) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// После удаления дубликатов очищаем лишние пустые строки
|
||||||
|
cleanMultiViewEmptyLines(multiViewLog);
|
||||||
|
|
||||||
if (removedCount > 0) {
|
if (removedCount > 0) {
|
||||||
console.log(`cleanMultiViewDuplicateLines: Удалено ${removedCount} дублированных строк`);
|
console.log(`cleanMultiViewDuplicateLines: Удалено ${removedCount} дублированных строк`);
|
||||||
}
|
}
|
||||||
@ -2656,7 +2677,8 @@ function cleanDuplicateLines(logElement) {
|
|||||||
const currentText = currentLine.textContent || currentLine.innerText || '';
|
const currentText = currentLine.textContent || currentLine.innerText || '';
|
||||||
const previousText = previousLine.textContent || previousLine.innerText || '';
|
const previousText = previousLine.textContent || previousLine.innerText || '';
|
||||||
|
|
||||||
if (currentText.trim() === previousText.trim() && currentText.trim() !== '') {
|
// Удаляем дублированные строки (включая пустые)
|
||||||
|
if (currentText.trim() === previousText.trim()) {
|
||||||
console.log(`cleanDuplicateLines: Удаляем дублированную строку: ${currentText.substring(0, 50)}...`);
|
console.log(`cleanDuplicateLines: Удаляем дублированную строку: ${currentText.substring(0, 50)}...`);
|
||||||
currentLine.remove();
|
currentLine.remove();
|
||||||
removedCount++;
|
removedCount++;
|
||||||
@ -2664,33 +2686,39 @@ function cleanDuplicateLines(logElement) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// После удаления дубликатов очищаем лишние пустые строки
|
||||||
|
if (logElement.classList.contains('multi-view-log')) {
|
||||||
|
cleanMultiViewEmptyLines(logElement);
|
||||||
|
} else {
|
||||||
|
cleanSingleViewEmptyLines(logElement);
|
||||||
|
}
|
||||||
|
|
||||||
if (removedCount > 0) {
|
if (removedCount > 0) {
|
||||||
console.log(`cleanDuplicateLines: Удалено ${removedCount} дублированных строк`);
|
console.log(`cleanDuplicateLines: Удалено ${removedCount} дублированных строк`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Функция для очистки лишних пустых строк в Single View
|
* Функция для радикальной очистки пустых строк в Single View
|
||||||
* Удаляет только лишние пустые строки, сохраняя переносы строк между логами
|
* Удаляет все пустые строки и лишние переносы строк
|
||||||
* @param {HTMLElement} logElement - элемент лога Single View
|
* @param {HTMLElement} logElement - элемент лога Single View
|
||||||
*/
|
*/
|
||||||
function cleanSingleViewEmptyLines(logElement) {
|
function cleanSingleViewEmptyLines(logElement) {
|
||||||
if (!logElement) return;
|
if (!logElement) return;
|
||||||
|
|
||||||
// Находим все строки в логе
|
|
||||||
const lines = Array.from(logElement.querySelectorAll('.line'));
|
|
||||||
let removedCount = 0;
|
let removedCount = 0;
|
||||||
|
|
||||||
// Удаляем только полностью пустые строки (строки без текста)
|
// Удаляем все пустые строки (элементы .line без текста)
|
||||||
|
const lines = Array.from(logElement.querySelectorAll('.line'));
|
||||||
lines.forEach(line => {
|
lines.forEach(line => {
|
||||||
const textContent = line.textContent || line.innerText || '';
|
const textContent = line.textContent || line.innerText || '';
|
||||||
if (textContent.trim() === '' && textContent.length === 0) {
|
if (textContent.trim() === '') {
|
||||||
line.remove();
|
line.remove();
|
||||||
removedCount++;
|
removedCount++;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Удаляем только полностью пустые текстовые узлы (не переносы строк)
|
// Удаляем все текстовые узлы, которые содержат только пробелы и переносы строк
|
||||||
const walker = document.createTreeWalker(
|
const walker = document.createTreeWalker(
|
||||||
logElement,
|
logElement,
|
||||||
NodeFilter.SHOW_TEXT,
|
NodeFilter.SHOW_TEXT,
|
||||||
@ -2701,23 +2729,24 @@ function cleanSingleViewEmptyLines(logElement) {
|
|||||||
const textNodesToRemove = [];
|
const textNodesToRemove = [];
|
||||||
let node;
|
let node;
|
||||||
while (node = walker.nextNode()) {
|
while (node = walker.nextNode()) {
|
||||||
// Удаляем только узлы, которые содержат только пробелы и переносы строк
|
|
||||||
if (node.textContent.trim() === '' && node.textContent.length > 0) {
|
|
||||||
// Проверяем, что это не просто перенос строки
|
|
||||||
const content = node.textContent;
|
const content = node.textContent;
|
||||||
if (content === '\n' || content === '\r\n') {
|
// Удаляем все узлы, которые содержат только пробелы, переносы строк или табуляцию
|
||||||
// Оставляем переносы строк
|
if (content.trim() === '') {
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Удаляем только если это множественные пробелы или табуляция
|
|
||||||
if (content.match(/^[\s\t]+$/)) {
|
|
||||||
textNodesToRemove.push(node);
|
textNodesToRemove.push(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
textNodesToRemove.forEach(node => node.remove());
|
textNodesToRemove.forEach(node => node.remove());
|
||||||
|
|
||||||
|
// Удаляем все пустые текстовые узлы между элементами .line
|
||||||
|
const allNodes = Array.from(logElement.childNodes);
|
||||||
|
for (let i = allNodes.length - 1; i >= 0; i--) {
|
||||||
|
const node = allNodes[i];
|
||||||
|
if (node.nodeType === Node.TEXT_NODE && node.textContent.trim() === '') {
|
||||||
|
node.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (removedCount > 0) {
|
if (removedCount > 0) {
|
||||||
console.log(`cleanSingleViewEmptyLines: Удалено ${removedCount} пустых строк`);
|
console.log(`cleanSingleViewEmptyLines: Удалено ${removedCount} пустых строк`);
|
||||||
}
|
}
|
||||||
@ -2737,6 +2766,40 @@ function normalizeSpaces(text) {
|
|||||||
return text.replace(/\s{2,}/g, ' ');
|
return text.replace(/\s{2,}/g, ' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Функция для периодической очистки пустых строк
|
||||||
|
* Вызывается автоматически каждые 2 секунды для поддержания чистоты логов
|
||||||
|
*/
|
||||||
|
function periodicCleanup() {
|
||||||
|
// Очищаем пустые строки в Single View
|
||||||
|
if (!state.multiViewMode && els.logContent) {
|
||||||
|
cleanSingleViewEmptyLines(els.logContent);
|
||||||
|
cleanDuplicateLines(els.logContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Очищаем пустые строки в мультипросмотре
|
||||||
|
if (state.multiViewMode) {
|
||||||
|
state.selectedContainers.forEach(containerId => {
|
||||||
|
const multiViewLog = document.querySelector(`.multi-view-log[data-container-id="${containerId}"]`);
|
||||||
|
if (multiViewLog) {
|
||||||
|
cleanMultiViewEmptyLines(multiViewLog);
|
||||||
|
cleanMultiViewDuplicateLines(multiViewLog);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Очищаем пустые строки в legacy панелях
|
||||||
|
Object.values(state.open).forEach(obj => {
|
||||||
|
if (obj.logEl) {
|
||||||
|
cleanSingleViewEmptyLines(obj.logEl);
|
||||||
|
cleanDuplicateLines(obj.logEl);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Запускаем периодическую очистку каждые 2 секунды
|
||||||
|
setInterval(periodicCleanup, 2000);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Функция для обработки специальных замен в MultiView логах
|
* Функция для обработки специальных замен в MultiView логах
|
||||||
* Выполняет специфичные замены для улучшения читаемости логов
|
* Выполняет специфичные замены для улучшения читаемости логов
|
||||||
@ -3140,14 +3203,14 @@ function handleLine(id, line){
|
|||||||
if (cls==='err') obj.counters.err++;
|
if (cls==='err') obj.counters.err++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Для Single View добавляем перенос строки после каждой строки лога
|
// Для Single View НЕ добавляем перенос строки после каждой строки лога
|
||||||
const html = `<span class="line ${cls}">${ansiToHtml(normalizedLine)}</span>\n`;
|
const html = `<span class="line ${cls}">${ansiToHtml(normalizedLine)}</span>`;
|
||||||
|
|
||||||
// Сохраняем все логи в буфере (всегда)
|
// Сохраняем все логи в буфере (всегда)
|
||||||
if (!obj.allLogs) obj.allLogs = [];
|
if (!obj.allLogs) obj.allLogs = [];
|
||||||
// Для Single View сохраняем обработанную строку, для MultiView - оригинальную
|
// Для Single View сохраняем обработанную строку, для MultiView - оригинальную
|
||||||
const processedLine = !state.multiViewMode ? processSingleViewSpecialReplacements(normalizedLine) : normalizedLine;
|
const processedLine = !state.multiViewMode ? processSingleViewSpecialReplacements(normalizedLine) : normalizedLine;
|
||||||
const processedHtml = `<span class="line ${cls}">${ansiToHtml(processedLine)}</span>\n`;
|
const processedHtml = `<span class="line ${cls}">${ansiToHtml(processedLine)}</span>`;
|
||||||
obj.allLogs.push({html: processedHtml, line: processedLine, cls: cls});
|
obj.allLogs.push({html: processedHtml, line: processedLine, cls: cls});
|
||||||
|
|
||||||
// Ограничиваем размер буфера
|
// Ограничиваем размер буфера
|
||||||
@ -3168,8 +3231,8 @@ function handleLine(id, line){
|
|||||||
return; // Пропускаем дублированную строку
|
return; // Пропускаем дублированную строку
|
||||||
}
|
}
|
||||||
|
|
||||||
// Создаем HTML с обработанной строкой для Single View (с переносом строки)
|
// Создаем HTML с обработанной строкой для Single View (без переноса строки)
|
||||||
const singleViewHtml = `<span class="line ${cls}">${ansiToHtml(singleViewProcessedLine)}</span>\n`;
|
const singleViewHtml = `<span class="line ${cls}">${ansiToHtml(singleViewProcessedLine)}</span>`;
|
||||||
|
|
||||||
obj.logEl.insertAdjacentHTML('beforeend', singleViewHtml);
|
obj.logEl.insertAdjacentHTML('beforeend', singleViewHtml);
|
||||||
|
|
||||||
@ -3226,7 +3289,7 @@ function handleLine(id, line){
|
|||||||
return; // Пропускаем дублированную строку
|
return; // Пропускаем дублированную строку
|
||||||
}
|
}
|
||||||
|
|
||||||
const multiViewHtml = `<span class="line ${cls}">${ansiToHtml(processedLine)}</span>\n`;
|
const multiViewHtml = `<span class="line ${cls}">${ansiToHtml(processedLine)}</span>`;
|
||||||
|
|
||||||
// Добавляем новую строку
|
// Добавляем новую строку
|
||||||
multiViewLog.insertAdjacentHTML('beforeend', multiViewHtml);
|
multiViewLog.insertAdjacentHTML('beforeend', multiViewHtml);
|
||||||
@ -3376,6 +3439,11 @@ async function switchToSingle(svc){
|
|||||||
els.logContent.insertAdjacentHTML('beforeend', logEntry.html);
|
els.logContent.insertAdjacentHTML('beforeend', logEntry.html);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Очищаем лишние пустые строки после восстановления логов
|
||||||
|
cleanSingleViewEmptyLines(els.logContent);
|
||||||
|
cleanDuplicateLines(els.logContent);
|
||||||
|
|
||||||
if (els.autoscroll && els.autoscroll.checked) {
|
if (els.autoscroll && els.autoscroll.checked) {
|
||||||
els.logContent.scrollTop = els.logContent.scrollHeight;
|
els.logContent.scrollTop = els.logContent.scrollHeight;
|
||||||
}
|
}
|
||||||
@ -3774,6 +3842,12 @@ async function refreshLogsAndCounters() {
|
|||||||
if (updatedContainer) {
|
if (updatedContainer) {
|
||||||
// Переключаемся на обновленный контейнер
|
// Переключаемся на обновленный контейнер
|
||||||
await switchToSingle(updatedContainer);
|
await switchToSingle(updatedContainer);
|
||||||
|
|
||||||
|
// Очищаем лишние пустые строки после переключения
|
||||||
|
if (els.logContent) {
|
||||||
|
cleanSingleViewEmptyLines(els.logContent);
|
||||||
|
cleanDuplicateLines(els.logContent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log('No container selected');
|
console.log('No container selected');
|
||||||
@ -3791,6 +3865,9 @@ els.clearBtn.onclick = ()=> {
|
|||||||
// Очищаем современный интерфейс
|
// Очищаем современный интерфейс
|
||||||
if (els.logContent) {
|
if (els.logContent) {
|
||||||
els.logContent.textContent = '';
|
els.logContent.textContent = '';
|
||||||
|
// Очищаем лишние пустые строки после очистки
|
||||||
|
cleanSingleViewEmptyLines(els.logContent);
|
||||||
|
cleanDuplicateLines(els.logContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Очищаем мультипросмотр
|
// Очищаем мультипросмотр
|
||||||
@ -4480,6 +4557,14 @@ window.addEventListener('keydown', async (e)=>{
|
|||||||
|
|
||||||
console.log('LogBoard+ инициализирован с исправлениями дублирования строк и правильными переносами строк в Single View и MultiView режимах');
|
console.log('LogBoard+ инициализирован с исправлениями дублирования строк и правильными переносами строк в Single View и MultiView режимах');
|
||||||
console.log('Для тестирования используйте: testDuplicateRemoval(), testSingleViewDuplicateRemoval(), testSingleViewEmptyLinesRemoval() или testSingleViewLineBreaks()');
|
console.log('Для тестирования используйте: testDuplicateRemoval(), testSingleViewDuplicateRemoval(), testSingleViewEmptyLinesRemoval() или testSingleViewLineBreaks()');
|
||||||
|
|
||||||
|
// Запускаем первоначальную очистку пустых строк
|
||||||
|
setTimeout(() => {
|
||||||
|
if (!state.multiViewMode && els.logContent) {
|
||||||
|
cleanSingleViewEmptyLines(els.logContent);
|
||||||
|
cleanDuplicateLines(els.logContent);
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user