Commit Graph

16 Commits

Author SHA1 Message Date
Nick Shirokov 22e929ecb3 feat(form-decompile,form-compile): tooltip элемента + фикс экранирования текста (кластер ToolTip)
Два дефекта вокруг текста <v8:content>, оба вскрылись на формах с подсказками.

1. ToolTip элемента (484 LOST в корпусе). <ToolTip> — прямой мультиязычный
   текст подсказки на элементе (UsualGroup 42150, Popup, Page, InputField,
   и почти все типы). Декомпилятор пропускал (как companion), компилятор не
   эмитил. Введён общий ключ tooltip (string|{ru,en}), как title:
   - декомпилятор: захват в Add-CommonProps;
   - компилятор: эмиссия в Emit-Title (сразу после Title) — покрывает все
     эмиттеры, зовущие Emit-Title.
   Попутно выяснилось, что Emit-Pages/Emit-CommandBar вовсе не звали Emit-Title
   (теряли и Title, и ToolTip), а Emit-Label эмитит Title по-своему — во все три
   добавлена обработка title/tooltip.

2. Экранирование кавычек. Esc-Xml экранировал " → &quot; в тексте элемента,
   но 1С в <v8:content> пишет " литерально (экранирует только & < >).
   Это ломало раундтрип любого текста с кавычками. Убрано экранирование " .

Декомпилятор (ps1) + компилятор (ps1+py) + spec (§4.1 tooltip). Покрытие:
input-fields (input+tooltip), pages (pages/page tooltip, page с кавычкой в
тексте — проверяет литеральность) — сертифицировано в 1С 8.3.24. Раундтрип
БанковскиеСчета/Wildberries/АдреснаяКнига: ToolTip и &quot; остаток = 0.
Регресс ps+py 33/33.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 15:36:30 +03:00
Nick Shirokov c43041c0b7 feat(form-decompile,form-compile): TitleLocation у LabelField/PictureField/Table (кластер TitleLocation)
TitleLocation обрабатывался только у input (passthrough), check/radio
(smart-default) и calendar. У LabelField (7362 в корпусе), PictureField (2479)
и Table (381) тег молча терялся — ни декомпилятор, ни компилятор его не знали.

Профиль доли элементов с тегом: Table 2.9%, LabelField 15.8%, PictureField
80.5% (но 20% без тега). Платформа НЕ всегда эмитит → выбран passthrough
(эмитим при наличии ключа, как у input/calendar), не smart-default. Корректно
и консистентно; переиспользован существующий ключ titleLocation + Map-TitleLoc.

Декомпилятор (ps1): захват titleLocation в трёх ветках. Компилятор (ps1+py):
эмиссия в Emit-LabelField/Emit-Table/Emit-PictureField в позиции по схеме.
spec §4.1: titleLocation вынесен в общие свойства с пометкой охвата.

Тест-покрытие добавлено в input-fields (labelField=left), picture-field
(picField=none), table (table=top) — снэпшоты сертифицированы в 1С 8.3.24.
Раундтрип 60 форм с TitleLocation на label/pic/table/radio: остатка нет.
Регресс ps+py 33/33.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 13:33:05 +03:00
Nick Shirokov 8998c0b5db feat(form-decompile,form-compile): свойства CalendarField (кластер CalendarField)
CalendarField терял специфичные свойства при раундтрипе: декомпилятор их не
читал, компилятор не эмитил. Пробел DSL (класс 3). CalendarField — длинный
хвост (18 форм на 17033, 0.1%), но элемент маленький и ограниченный → решено
покрыть целиком, убрав класс молчаливых потерь.

Добавлены ключи (passthrough, эмитятся только при наличии): selectionMode,
showCurrentDate, widthInMonths, heightInMonths, showMonthsPanel. Плюс
подключён общий titleLocation (раньше у календаря не обрабатывался).

Порядок тегов выверен по корпусу (18 форм): DataPath > Title > TitleLocation
> [layout] > SelectionMode > ShowCurrentDate > WidthInMonths > HeightInMonths
> ShowMonthsPanel > companions > Events.

Декомпилятор (ps1) + компилятор (ps1+py) + spec. Новый тест-кейс calendar
(два календаря: со скалярами+событием и с months-panel), сертифицирован
в 1С 8.3.24. Регресс ps+py 33/33.

Tooltip-свойства календаря (ToolTip/ToolTipRepresentation) намеренно оставлены
будущему общему tooltip-кластеру. Раундтрип календарных форм: ПериодКомандировки
→ match; остаточный TitleLocation на radio/table — отдельная находка (BACKLOG).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 13:08:09 +03:00
Nick Shirokov 4c2c72abce feat(form-decompile,form-compile): унификация событий элементов на events-мапу (кластер Events DSL)
Несогласованность DSL: события ФОРМЫ описывались интуитивной мапой
events:{Событие:Обработчик}, а события ЭЛЕМЕНТА — двумя сущностями
on:[...] + handlers:{...}. Два способа для одного понятия путали модель.

Унифицировано на единую мапу events:{Событие:ИмяОбработчика} на форме И
элементах (как form-level). Декомпилятор эмитит только её, с явными именами
обработчиков (прозрачно, консистентно с form-level).

Компилятор (ps1+py):
- Emit-Events читает events-мапу (основной формат); значение null/"" →
  имя по конвенции ИмяЭлемента+суффикс (прощающий fallback).
- legacy on/handlers по-прежнему принимаются ради совместимости (не эмитятся).
- choiceButton: проверка StartChoice через оба формата (Test-ElementEvent).
- events добавлен в whitelist ключей элемента.

Декомпилятор: Get-Events → упорядоченная мапа {Событие:Обработчик} в порядке
документа; убраны on/handlers и инверсия авто-имён.

spec/SKILL.md: events как единственный рекомендованный формат, on/handlers
помечены legacy. В SKILL.md только явные имена (null-сахар — деталь spec,
инструкцию не раздуваем).

Корпус acc_8.3.24: 190 элементов в 114/400 форм теряли Events до фикса (баг
on/handlers разобран отдельным коммитом). Раундтрип 2.17: Events ушли из топа
LOST, match 4→6, 0 compile-fail. Регресс ps+py 32/32, снэпшот events (добавлен
блок Events у поля с переименованным обработчиком) сертифицирован в 1С 8.3.24.

Follow-up: form-edit использует расширенный on с {event,callType} —
унификация отдельным решением (см. BACKLOG).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 12:46:56 +03:00
Nick Shirokov 3483802ab0 docs(form-dsl-spec): уточнение семантики "" — суппресс-маркер, не «дефолт платформы»
"" означает «не выводить тег» (платформа применит своё рантайм-умолчание),
а не «значение = дефолту платформы». Разведение дефолта эмиссии и дефолта рантайма.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 22:02:38 +03:00
Nick Shirokov 3b0061c8a0 feat(form-decompile,form-compile): мультиязычный текст (кластер I)
БАГ: Emit-MLText стрингифицировал мультиязычный объект {ru,en} →
<v8:content>@{ru=…; en=…}</v8:content> (мусор). ERP — двуязычная конфигурация,
поэтому это доминирующий пробел раундтрипа (item/content/lang).

- compiler PS1+PY: Emit-MLItems/emit_ml_items — по <v8:item> на язык; все
  вызывающие (Title/ToolTip/InputHint/реквизиты/колонки/команды/форма + Emit-Label)
  передают сырой объект вместо стрингификации. choice presentation уже был мультиязычен.
- decompiler уже давал {ru,en}; убран мёртвый titleFormatted (компилятор выводит formatted из hyperlink).
- docs/form-dsl-spec: title/tooltip/inputHint принимают объект {ru,en,…}.
- tests: groups (title {ru,en}) сертифицирован в 1С.

Эффект (220 форм 2.17): item 3909→1475, content 3193→737, lang 1861→635. Регресс 32/32 PS1+PY.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 21:28:53 +03:00
Nick Shirokov b4fc9bf42c feat(form-decompile,form-compile): листовые свойства полей + фикс Hiperlink (кластер L)
БАГ: у LabelField платформенный тег <Hiperlink> (опечатка 1С), компилятор
эмитил <Hyperlink> — гиперссылка не работала и не роундтрипилась. Проверено
по корпусу: LabelField→Hiperlink во всех версиях формата (2.17 и 2.20).

- compiler PS1+PY: LabelField <Hiperlink>; EditMode (input/check/labelField);
  CheckBoxType (check, умный дефолт Auto + suppress как radioButtonType).
- decompiler: editMode, checkBoxType (Auto→опустить), markIncomplete (раньше не ловился),
  labelField читает <Hiperlink>.
- docs/form-dsl-spec: editMode, checkBoxType, примечание про Hiperlink.
- tests: input-fields расширен (editMode/checkBoxType/labelField+hyperlink), сертифицирован.

Регресс 32/32 PS1+PY, churn по флажкам обновлён и сертифицирован.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 20:29:31 +03:00
Nick Shirokov 9c1ea1662a feat(form-decompile,form-compile): CommandSet/excludedCommands таблиц (кластер F)
CommandSet встречается на Table (23) и Form (8). Форменный excludedCommands
уже поддержан, табличный — нет.

- compiler PS1+PY: Emit-Table — excludedCommands → <CommandSet>; заодно
  viewStatusLocation/searchControlLocation (из того же блока свойств таблицы).
- decompiler: Table — CommandSet→excludedCommands, searchStringLocation
  (раньше не ловился), viewStatusLocation/searchControlLocation.
- docs/form-dsl-spec: excludedCommands + view/searchControl у таблицы.
- tests: table расширен, сертифицирован в 1С.

ExcludedCommand ушёл из топа LOST. Регресс 32/32 PS1+PY, churn нулевой.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 19:18:17 +03:00
Nick Shirokov 0941fc717d feat(form-decompile,form-compile): семантика TitleLocation (кластер G2)
Принцип: компилятор не эмитит значение, равное дефолту платформы (который
платформа сама не пишет в XML). Умный дефолт (check→Right, radio→None) —
отдельная вещь, эмитится (он ≠ дефолт платформы Left).

- net ключа titleLocation → умный дефолт; titleLocation: "" → подавить
  (дефолт платформы); значение → эмитить с маппингом регистра.
- compiler PS1+PY: Emit-TitleLocation/emit_title_location + Map-TitleLoc
  (общий маппинг; у check раньше его не было — сырьё).
- decompiler: Add-TitleLocation (дефолт → опустить, нет тега → "", иначе значение).
- docs/form-dsl-spec: семантика titleLocation у check/radio.
- tests: input-fields расширен (Right-дефолт / ""-подавление / явный Top), сертифицирован.

АварийныйРежим: полный MATCH. Регресс 32/32 PS1+PY, churn нулевой.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 18:53:28 +03:00
Nick Shirokov 4ba1e595bf feat(form-decompile,form-compile): семантика title (кластер G)
Над-генерация заголовков элементов из имени. Различаем:
- нет ключа title → авто-вывод из имени (помощь модели при создании форм);
- title: "" → подавить (<Title> не эмитим);
- непустая строка → как есть.

- compiler PS1+PY: Emit-Title/emit_title + Emit-Label проверяют наличие ключа,
  а не truthiness (раньше "" триггерило авто-вывод).
- decompiler: ставит title:"" для авто-выводящих типов (page/popup/label,
  непривязанные поля, button без команды), когда <Title> в оригинале отсутствует.
- docs/form-dsl-spec: семантика title.
- tests: pages демонстрирует title:"" (+snapshot, сертифицирован в 1С).

АварийныйРежим: diff 13→1. Регресс 32/32 PS1+PY, churn нулевой.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 18:32:02 +03:00
Nick Shirokov e777ded8d2 feat(form-decompile,form-compile): геометрия/layout единым хелпером (кластер E)
- compiler PS1+PY: общий Emit-Layout/emit_layout (width/height/stretch/maxWidth/
  maxHeight/autoMax*/skipOnInput/groupHorizontalAlign/groupVerticalAlign/
  horizontalAlign), вызывается во всех эмиттерах; inline-дубли убраны. Спец-квирки
  сохранены (input multiLine→autoMaxWidth, table height→HeightInTableRows).
- PictureDecoration LoadTransparent больше не захардкожен true — управляется
  loadTransparent (дефолт false).
- decompiler: Add-Layout (DRY, один вызов на элемент), table HeightInTableRows,
  picture loadTransparent.
- docs/form-dsl-spec: блок общих layout-свойств (4.1a), loadTransparent у picture.
- tests: groups расширен layout-свойствами (+snapshot, сертифицирован в 1С).

Churn снапшотов нулевой. АварийныйРежим: LOST полностью закрыт (остаток — над-генерация).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 17:51:13 +03:00
Nick Shirokov 67eaa1c3c8 feat(form-decompile,form-compile): командные панели (кластер D)
- form-decompile: форменный AutoCommandBar → autoCmdBar-элемент; ButtonGroup;
  команды tooltip/currentRowUse; choiceList value type (число/булево) — раньше.
- form-compile (PS1+PY): новый тип ButtonGroup; команды ToolTip/CurrentRowUse.
- docs/form-dsl-spec: buttonGroup, autoCmdBar (панель формы), tooltip/currentRowUse.
- tests: кейс form-compile/button-group (+snapshot, платформенно валидирован).

АварийныйРежим раундтрип: diff 44→18. Регресс form-compile зелёный (PS1+PY).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 16:22:07 +03:00
Nick Shirokov 3a89aa21e6 docs: картиночные колонки readTable + valuesPicture в form DSL
- web-test-guide: раздел про picture-колонки readTable (pic:N/'',
  truthy-наличие, именование по тултипу, read/assert-only — не селектор).
- form-dsl-spec: ключи valuesPicture/loadTransparent у picField.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 20:52:07 +03:00
Nick Shirokov 4f9d9aee97 feat(form-compile): группировка колонок таблицы (ColumnGroup)
Новый DSL-ключ columnGroup со значением-ориентацией horizontal/vertical/inCell
для элемента <ColumnGroup> внутри columns таблицы. Поддерживает вложение,
showTitle/showInHeader/width, тихие синонимы ColumnGroup и ГруппаКолонок.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 11:48:35 +03:00
Nick Shirokov 5690c82ab8 docs(form-dsl-spec): radio (RadioButtonField) в спецификации DSL
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 18:45:00 +03:00
Nick Shirokov cc2595b57a Add form-compile skill for generating Form.xml from JSON DSL
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 11:57:58 +03:00