---
name: prtv-text-element
description: Нативный элемент «Текст» конструктора вывесок PRTV (prtv.pro) — вход в редактирование и выход, панель TinyMCE (шрифты, размер, цвет, интервалы), какие правки сохраняются, а какие молча теряются, ловушка тройного клика в строках меню с ценой справа, замена текста через Ctrl+A, раскладка строк меню, особенности отображения, когда выбрать Текст, а когда HTML-блок. Использовать, когда нужно написать, переоформить или массово поправить текст, цены или позиции меню на слайде в prtv.pro, или когда правки текста пропадают после перезагрузки. Triggers (EN) text element, font, menu prices, menu rows, text not saved, TinyMCE.
license: CC-BY-4.0
metadata:
  author: PRTV (prtv.pro)
  product: Конструктор цифровых вывесок PRTV (prtv.pro)
  version: "1.1"
  date: "2026-09-26"
  language: ru
  scope: интерфейс редактора + чтение состояния страницы из DOM; без вызовов внутреннего API
---

# Элемент «Текст» в конструкторе PRTV

Родной элемент **«Текст»** — место для всего, что читают: позиций меню, цен, заголовков, описаний. Это единственный элемент, который заказчик потом правит сам, не трогая код. Внутри — редактор форматированного текста (TinyMCE), содержимое которого хранится как HTML: абзацы и спаны с инлайновыми стилями плюс небольшой встроенный стиль с умолчаниями элемента. Этот скилл — о том, как править это содержимое так, чтобы правка пережила перезагрузку. Положение, размер, глубина и анимация элемента — в prtv-element-layout, карта редактора — в prtv-editor-overview.

## 1. Создание и выделение

- Левая панель → **«Текст»** добавляет текстовый элемент на активный слайд в левый верхний угол, 500×120 px, со стилями элементов по умолчанию этого слайда (Arial 24 px чёрный, если в настройках слайда не задано иное — см. prtv-slide-settings).
- **Один клик** по текстовому элементу выделяет его как бокс (появляется рамка, открывается панель элемента).
- **Двойной клик** входит в правку текста: появляется узел `[contenteditable="true"]`, над холстом показывается тулбар форматирования.

Вход в правку — самый ненадёжный шаг всей процедуры для агента: клик и следом двойной клик обычно требуют 2–5 попыток. После каждой попытки проверять `document.querySelector('[contenteditable="true"]')` и останавливаться, как только узел появился. Никогда не давать серию двойных кликов вслепую — лишний клик по выделенному элементу превращается в драг и уносит его за пределы слайда.

## 2. Правка, замена, выход

- **Заменить весь текст**: в режиме правки Ctrl+A, затем набрать. Набранный текст сохраняется всегда.
- **Выйти из правки**: клик по пустому месту холста *слева от слайда*. Escape ненадёжен. Не кликать рядом с полосой миниатюр внизу — там по наведению появляются кнопки, включая удаление слайда.
- Сохранение автоматическое; после изменения появляется «Сохранено». Окончательная проверка — перезагрузка страницы: сохранено то, что её пережило.
- Enter внутри текста создаёт новый абзац. Когда нужно только подтвердить значение в поле тулбара (кегль), Enter нажимать в этом поле, а не в тексте.

Драг *выделенного* текстового элемента не двигает его, а открывает правку. Чтобы перенести — сначала снять выделение (Escape или клик мимо), потом тянуть невыделенный элемент.

## 3. Тулбар

Слева направо:

`отменить повторить | жирный курсив подчёркнутый зачёркнутый · шрифт · кегль · h1 · таблица | цвет текста · цвет фона · выравнивание · маркированный список · нумерованный список · уменьшить отступ · увеличить отступ · межстрочный интервал · межбуквенный интервал · убрать форматирование`

Что важно:

- **Шрифт** — выпадающий список из 26 встроенных шрифтов (перечень в prtv-editor-overview) плюс шрифты, добавленные в настройках слайд-шоу → «Дополнительные шрифты». **Шрифт ставится только через этот список.** Он записывает шрифт с `!important` — именно это перебивает встроенный стиль элемента; шрифт, поставленный любым другим способом, игнорируется.
- **Кегль** — поле ввода. Клик по нему, Ctrl+A, значение с единицами (`56px`), Enter. Значения — в пространстве слайда 1920×1080.
- **Жирный** — существуют только начертания 400 и 700. Вариативные шрифты усекаются до этих двух.
- **Цвет текста** — составная кнопка. Клик по стрелке → палитра из 25 образцов → «Custom color» → поле hex → Save. Дождаться, пока поле hex действительно получит фокус, прежде чем печатать; ранний ввод уходит в тело текста и затирает выделение.
- **Межстрочный** и **межбуквенный интервал** — отдельные кнопки.
- **Убрать форматирование** — снимает инлайновые стили с выделения; полезно перед переоформлением текста, вставленного откуда-то ещё.

Чего в тулбаре нет: text-transform (заглавные набирать заглавными), табличных цифр и другой специальной CSS-типографики. Если дизайн этого требует, такой фрагмент уходит в HTML-блок — см. prtv-html-block-animation.

## 4. Что сохраняется, а что молча теряется

Содержимое элемента хранится в состоянии редактора; видимый текст — только его отображение. При потере фокуса и при перезагрузке редактор перестраивает отображение из состояния, поэтому **всё, что скрипт записал прямо в DOM, выглядит применённым, а потом исчезает**. На одной живой сессии это стоило двух полных проходов по шрифтам меню, прежде чем было замечено.

| Правка | Сохраняется? |
|---|---|
| Реальный набор, Ctrl+A + набор, вставка | да |
| Команды тулбара (шрифт, кегль, жирный, цвет, выравнивание, интервалы) | да |
| Стиль, записанный скриптом в DOM без реального ввода после него | нет — откатывается при потере фокуса |
| Содержимое, заменённое скриптом без нажатия клавиши после | может откатиться при потере фокуса |
| `gap` на строке, `transform: scale()` на спане | отфильтровываются даже с нажатием клавиши |

**Приём с нажатием клавиши.** Изменение DOM, сделанное *до* реального нажатия клавиши, попадает в то, что редактор сериализует: при нажатии он читает живое содержимое. Значит: применить стиль к DOM скриптом, затем нажать в редакторе End, Space, Backspace (реальные события клавиатуры). Так фиксируются структурные стили — `flex: 1` на спане названия, отступ, значение `display`. То, что фильтр редактора выбрасывает (`gap`, `transform`), так не зафиксировать; вместо `gap` использовать `flex: 1`, вместо `transform: scale()` — `font-size`.

**Проверка.** Клик мимо, перезагрузка страницы, затем поиск ожидаемого фрагмента в HTML элемента (только чтение):

```js
document.getElementById('slide-element-<id>').innerHTML.includes('flex: 1')
```

Если после перезагрузки фрагмента нет — правка не сохранилась; повторить с реальным нажатием клавиши после изменения.

## 5. Ловушка triple-click на строках меню

Строка меню — обычно один абзац с двумя спанами, названием и ценой, свёрстанный через `display: flex; justify-content: space-between`, чтобы цена стояла у правого края.

Если выделить абзац целиком (тройной клик) и применить шрифт из тулбара, редактор **обернёт всё содержимое в один новый спан**. У строки остаётся единственный flex-элемент, и цена прилипает к названию. Лечится применением шрифта **по каждому спану отдельно**: выделить название — применить; выделить цену — применить.

Для множества строк выделять спаны скриптом (выделение — не правка DOM и сохранению не мешает), а шрифт применять кликом по тулбару:

```js
window.__selNext = function () {
  const ed = document.querySelector('[contenteditable="true"]'); if (!ed) return 'noed';
  const sp = [...ed.querySelectorAll('span')].filter(s =>
    s.children.length === 0 && s.textContent.trim() &&
    parseFloat(getComputedStyle(s).fontSize) >= 29 &&
    !/НужныйШрифт/.test(getComputedStyle(s).fontFamily));
  if (!sp.length) return 'done';
  ed.focus();
  const r = document.createRange(); r.selectNodeContents(sp[0]);
  const sel = getSelection(); sel.removeAllRanges(); sel.addRange(r);
  return sp[0].textContent.trim();
};
```

Цикл: `__selNext()` → клик по списку шрифтов (`.tox-tbtn--select`) → клик по нужному пункту (`.tox-collection__item`) → повторять до `'done'`. Фильтр пропускает спаны, у которых нужный шрифт уже стоит, поэтому цикл можно безопасно перезапускать. Координаты тулбара брать из DOM: внутри одного элемента они стабильны, между элементами меняются.

## 6. Строки меню и вставка разметки

- Раскладка строки: один абзац, `display: flex; justify-content: space-between`, спан названия с `flex: 1`, за ним спан цены. С `flex: 1` на названии цена прижимается к правому краю при любой длине текста; без него расстояние зависит от набранных пробелов.
- В **только что созданный** текстовый элемент целый блок размеченных строк можно вставить разом (вставкой из буфера или командой браузера insertHTML после выделения содержимого элемента) — он сохраняется. В **существующем** элементе такая вставка ненадёжна — править построчно и фиксировать нажатием клавиши.
- Пробелы, неразрывные пробелы и любые набранные символы сохраняются; редактор не фильтрует содержимое, только некоторые стили.
- Текст поверх фото, ширина боксов, кегли и безопасные зоны — prtv-element-layout §7. Надёжной формулы «кегль × число символов = ширина» для родного текста нет — закладывать бокс на 30–40 % шире наивного расчёта.

## 7. Известные особенности отображения

- Знак рубля ₽ на холсте редактора показывается как «Р»; на телевизоре он выводится правильно. Знаки валют оценивать в предпросмотре или на экране, а не на холсте.
- Правка руками может разбить абзац надвое; новый фрагмент может потерять инлайновые стили исходного. Заново применить к нему шрифт и цвет из тулбара.
- Шрифт, добавленный в настройках слайд-шоу, проверять в предпросмотре или на телевизоре — холст редактора и плеер рендерят по-разному.
- Встроенный стиль элемента задаёт умолчания для всего элемента; стиль из тулбара его перебивает. Стили из `<style>` HTML-блока глобальны для страницы и тоже могут целиться в родной текст (см. §8).

## 8. Анимация родного текста без превращения в HTML

Пресеты панели зацикливаются при количестве повторов 0 (пульс, вспышка — см. prtv-element-layout), но блик или переливание цвета они не умеют. Чтобы дать заголовку непрерывный свой эффект **и оставить его редактируемым**, оставить его элементом «Текст» и добавить маленький HTML-блок, чей `<style>` целится в спан текста по одному из инлайновых свойств, например по кеглю:

```css
.text-widget span[style*="font-size: 52px"] { … animation: promoShine 5s linear infinite; }
```

Полный рецепт с keyframes градиентного блика — в prtv-html-block-animation. Правка слов эффект не ломает.

## 9. Бегущая строка — второй родной текст

У элемента **«Бегущая строка»** своя панель: текст, скорость, направление прокрутки, размер шрифта, шрифт, цвет текста, цвет фона, анимация, глубина. Скорость × 10 = пикселей в секунду (20 → 200 px/с); длительность цикла зависит от длины текста, поэтому синхронизировать строку с отдельно анимированной картинкой нельзя. Подробности и обходной приём «транспарант за самолётом» — в prtv-html-block-animation.

## 10. «Текст» или HTML-блок?

Правило с реальных меню-бордов: **всё, что читают — названия, цены, описания, заголовки, — в родные элементы «Текст»**, чтобы заведение могло править их само. HTML-блоки — для того, чего «Текст» не умеет: градиентные плашки (родного градиента нет), информеры по URL, непрерывная анимация, таблицы с точечными лидерами, капитель и табличные цифры.

## Чего не делать

- Не ставить шрифт никаким способом, кроме списка в тулбаре.
- Не применять шрифт ко всей flex-строке разом — по спанам.
- Не считать правку DOM скриптом сохранённой; фиксировать реальным нажатием клавиши и проверять перезагрузкой.
- Не печатать hex-цвет, пока поле пользовательского цвета не получило фокус.
- Не нажимать Enter в тексте, чтобы «подтвердить» значение тулбара.
- Не судить о знаке рубля по холсту.
- Не давать вслепую серии двойных кликов для входа в правку — проверять `[contenteditable="true"]` после каждой попытки.
- Не класть редактируемое содержимое меню в HTML-блок.

## Связанные скиллы

prtv-editor-overview · prtv-element-layout · prtv-slide-settings · prtv-html-block-animation · prtv-agent-rules
