Corp/docs/completed/MESSAGE_NEWLINES_FIX.md
Игорь Надеин 48631f43fd Реорганизация документации и скриптов проекта
- Создана структура docs/ с категориями: completed, guides, architecture, diagnostic, in-progress, reports
- Перемещено 47+ MD файлов из корня проекта в docs/
- Удалено 6 устаревших/дублирующихся файлов
- Создана структура backend/scripts/ для тестов и утилит
- Перемещено 35 Python скриптов в backend/scripts/
- Создана структура backend/docs/ для технической документации
- Перемещено 12 MD файлов backend в backend/docs/
- Перемещены LDAP тестовые данные в backend/tests/fixtures/
- Добавлены README файлы для навигации
- Добавлены правила в .github/copilot-instructions.md для размещения документации

Результат:
- Корень проекта: только README.md
- Корень backend/: только manage.py и Django приложения
- Вся документация организована в структурированные папки
2025-12-26 13:49:51 +03:00

5.9 KiB
Raw Blame History

Исправление: Поддержка переносов строк в сообщениях

Дата: 4 декабря 2025 г.
Проблема: Сообщения не отображали переносы строк (многострочный текст показывался одной строкой)


🔴 Проблема

При отправке многострочных сообщений в чате (с нажатием Enter для переноса строки), текст отображался одной строкой, игнорируя все переносы.

Пример:

Ввод пользователя:

Строка 1
Строка 2
Строка 3

Отображалось как:

Строка 1 Строка 2 Строка 3

🔍 Анализ

1. Рендеринг сообщений (messageRenderer.js)

// Строка 210
${msg.content ? `<div>${this.escapeHtml(msg.content)}</div>` : ''}

// Метод escapeHtml (строка 318)
escapeHtml(text) {
    const div = document.createElement('div');
    div.textContent = text;
    return div.innerHTML;
}

Метод escapeHtml() корректно экранирует HTML, но переносы строк (\n) остаются в виде символов, которые браузер игнорирует в обычном режиме отображения.

2. CSS стили bubble (chat-detail.css)

.bubble {
  border-radius: 16px;
  padding: var(--space-1) var(--space-2);
  word-break: break-word;
  /* white-space не указан - по умолчанию: normal */
  box-shadow: 0 1px 2px rgba(0, 0, 0, .06);
}

По умолчанию white-space: normal схлопывает последовательные пробелы и переносы строк в один пробел.


✅ Решение

Добавлено CSS свойство white-space: pre-wrap для класса .bubble:

.bubble {
  border-radius: 16px;
  padding: var(--space-1) var(--space-2);
  word-break: break-word;
  white-space: pre-wrap; /* ← ДОБАВЛЕНО */
  box-shadow: 0 1px 2px rgba(0, 0, 0, .06);
}

Что делает white-space: pre-wrap:

Свойство Переносы строк Пробелы Перенос текста
normal (по умолчанию) ❌ Игнорируются ❌ Схлопываются ✅ Есть
pre ✅ Сохраняются ✅ Сохраняются ❌ Нет
pre-wrap ✅ Сохраняются ✅ Сохраняются ✅ Есть
pre-line ✅ Сохраняются ❌ Схлопываются ✅ Есть

pre-wrap — идеальный вариант для чатов:

  • ✅ Сохраняет переносы строк
  • ✅ Сохраняет множественные пробелы (для форматирования)
  • ✅ Автоматически переносит длинные строки (не вылезает за пределы)

🎨 Результат

До исправления:

Привет! Как дела? Давно не виделись!

После исправления:

Привет!
Как дела?
Давно не виделись!

🧪 Тестирование

Примеры для тестирования:

  1. Простой перенос:

    Строка 1
    Строка 2
    
  2. Множественные переносы:

    Строка 1
    
    
    Строка 2 (после двух пустых строк)
    
  3. Длинная строка с переносом:

    Очень длинная строка текста, которая должна автоматически перенестись на новую строку если не помещается в ширину bubble
    
  4. Форматированный текст:

    Список покупок:
    - Молоко
    - Хлеб
    - Масло
    
  5. Код или табуляция:

    function hello() {
      console.log("Hello!");
    }
    

📁 Изменённые файлы

  • ✅ backend/static/css/components/chat-detail.css - добавлен white-space: pre-wrap для .bubble

🔄 Альтернативные решения (не использовались)

Вариант 2: Конвертация \n в <br> в JavaScript

// В messageRenderer.js
formatContent(text) {
    return this.escapeHtml(text).replace(/\n/g, '<br>');
}

// Использование:
${msg.content ? `<div>${this.formatContent(msg.content)}</div>` : ''}

Недостатки:

  • ❌ Не сохраняет множественные пробелы
  • ❌ Требует изменения JS кода
  • ❌ Менее гибко для будущих доработок

Вариант 3: CSS white-space: pre-line

.bubble {
  white-space: pre-line;
}

Недостатки:

  • ❌ Не сохраняет множественные пробелы (схлопывает в один)
  • ❌ Менее удобно для форматированного текста

🎯 Выводы

  1. ✅ CSS решение (white-space: pre-wrap) — наиболее правильное и простое
  2. ✅ Не требует изменений в JavaScript
  3. ✅ Поддерживает все виды форматирования текста
  4. ✅ Совместимо с существующей логикой экранирования HTML
  5. ✅ Работает для всех типов сообщений (свои и чужие)

Статус: ✅ Исправлено
Тестирование: Требуется проверка в браузере