From 47e980f932c74a14519b502e1283244c967759e7 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sat, 13 Jun 2026 16:39:00 +0300 Subject: [PATCH] =?UTF-8?q?feat(form-decompile,form-compile):=20itemsUserS?= =?UTF-8?q?ettingPresentation=20=D0=B2=20=D0=B4=D0=B5=D1=81=D0=BA=D1=80?= =?UTF-8?q?=D0=B8=D0=BF=D1=82=D0=BE=D1=80=D0=B5=20ListSettings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ListSettings может нести items-уровневую подпись (рядом с itemsViewMode/itemsUserSettingID). Get-ListSettingsShape ронял её в канон-fallback (unknown top-level element → return $null) → терялась. Аналог container-level userSettingPresentation (commit 66817312), но items-уровень. Декомпилятор: захват itemsUserSettingPresentation в дескриптор (Get-PresByType — форма по xsi:type). Компилятор: новый case в потреблении дескриптора (Emit-USPresentation / emit_us_presentation). Зеркало py. Корпус 8.3.24: 2 формы (ОплатаПлатежнойКартой/ФормаПлатежиПоРеестрам, …): match 0→2, TOTAL→0. ps1==py байт-в-байт. Регресс 43/43. Spec обновлён. Co-Authored-By: Claude Opus 4.8 (1M context) --- .claude/skills/form-compile/scripts/form-compile.ps1 | 3 ++- .claude/skills/form-compile/scripts/form-compile.py | 4 +++- .claude/skills/form-decompile/scripts/form-decompile.ps1 | 5 +++-- docs/form-dsl-spec.md | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.claude/skills/form-compile/scripts/form-compile.ps1 b/.claude/skills/form-compile/scripts/form-compile.ps1 index 0d2b225a..037df42d 100644 --- a/.claude/skills/form-compile/scripts/form-compile.ps1 +++ b/.claude/skills/form-compile/scripts/form-compile.ps1 @@ -1,4 +1,4 @@ -# form-compile v1.164 — Compile 1C managed form from JSON or object metadata +# form-compile v1.165 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$JsonPath, @@ -5793,6 +5793,7 @@ function Emit-Attributes { 'conditionalAppearance' { $bus = if ($meta -match 'u') { $script:CANON_CA_ID } else { $null }; Emit-ConditionalAppearance -items $st.conditionalAppearance -indent $lsi -blockViewMode $bvm -blockUserSettingID $bus -blockUserSettingPresentation $bpres } 'itemsViewMode' { X "$lsiNormal" } 'itemsUserSettingID' { X "$lsi$($script:CANON_ITEMS_ID)" } + 'itemsUserSettingPresentation' { Emit-USPresentation -val $pv -tag "dcsset:itemsUserSettingPresentation" -indent $lsi } 'structure' { Emit-ListGrouping (Get-ListGroupingValue $st) $lsi } } } diff --git a/.claude/skills/form-compile/scripts/form-compile.py b/.claude/skills/form-compile/scripts/form-compile.py index f5c00d76..0dd9a9d0 100644 --- a/.claude/skills/form-compile/scripts/form-compile.py +++ b/.claude/skills/form-compile/scripts/form-compile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# form-compile v1.164 — Compile 1C managed form from JSON or object metadata +# form-compile v1.165 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import copy @@ -5570,6 +5570,8 @@ def emit_attributes(lines, attrs, indent, conditional_appearance=None): lines.append(f'{lsi}Normal') elif tag == 'itemsUserSettingID': lines.append(f'{lsi}{CANON_ITEMS_ID}') + elif tag == 'itemsUserSettingPresentation': + emit_us_presentation(lines, lsi, 'dcsset:itemsUserSettingPresentation', pv) elif tag == 'structure': emit_list_grouping(lines, get_list_grouping_value(s), lsi) else: diff --git a/.claude/skills/form-decompile/scripts/form-decompile.ps1 b/.claude/skills/form-decompile/scripts/form-decompile.ps1 index 1eed6508..c8bac26c 100644 --- a/.claude/skills/form-decompile/scripts/form-decompile.ps1 +++ b/.claude/skills/form-decompile/scripts/form-decompile.ps1 @@ -1,4 +1,4 @@ -# form-decompile v0.139 — Decompile 1C managed Form.xml to JSON DSL (draft) +# form-decompile v0.140 — Decompile 1C managed Form.xml to JSON DSL (draft) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills # ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью. param( @@ -144,8 +144,9 @@ function Get-ListSettingsShape { } else { $shape[$tag] = $code } } elseif ($tag -eq 'itemsViewMode') { $shape['itemsViewMode'] = $true } elseif ($tag -eq 'itemsUserSettingID') { $shape['itemsUserSettingID'] = $true } + elseif ($tag -eq 'itemsUserSettingPresentation') { $shape['itemsUserSettingPresentation'] = Get-PresByType $child } # items-уровневая подпись (форма по xsi:type) elseif ($tag -eq 'item') { if ($hasGrouping) { $shape['structure'] = $true } else { return $null } } - else { return $null } # dataParameters/itemsUserSettingPresentation/… → канон-fallback + else { return $null } # dataParameters/… → канон-fallback } # Полный каноничный скелет → опускаем (компилятор регенерит) if ($shape.Count -eq 5 -and $shape['filter'] -eq 'vu' -and $shape['order'] -eq 'vu' -and ` diff --git a/docs/form-dsl-spec.md b/docs/form-dsl-spec.md index fe5c688e..87dd7c51 100644 --- a/docs/form-dsl-spec.md +++ b/docs/form-dsl-spec.md @@ -962,7 +962,7 @@ Forgiving-синонимы типа: XML-имя (`SpreadSheetDocumentField`) и Пустой блок настроек компоновщика (`ListSettings`) генерируется автоматически (каноничный полный скелет платформы — filter+order+conditionalAppearance+itemsViewMode+itemsUserSettingID, ~93% форм); указывать ничего не нужно. -| `listSettings` | object | **Дескриптор формы скелета ``** — только для НЕ-каноничных (частичных/минимальных) форм. Ordered-карта present top-level элементов: контейнеры `filter`/`order`/`conditionalAppearance` → блок-мета (`"vu"`=viewMode+userSettingID, `"u"`=только userSettingID, `"v"`, `""`); `itemsViewMode`/`itemsUserSettingID` → `true`. Если контейнер несёт собственный `userSettingPresentation` (кастомная подпись настройки), значение — объект `{ meta: "u", presentation: "Текст" | {ru,en} }` (presentation по форме значения: строка → `xs:string`, объект → `LocalStringType`). Компилятор эмитит ТОЛЬКО указанные части (контент берёт из `filter`/`order`/`conditionalAppearance`). Нет ключа → полный каноничный скелет. Пустой объект `{}` → self-closing `` (оригинал без скелета). Декомпилятор пишет дескриптор только для отклонений от канона | +| `listSettings` | object | **Дескриптор формы скелета ``** — только для НЕ-каноничных (частичных/минимальных) форм. Ordered-карта present top-level элементов: контейнеры `filter`/`order`/`conditionalAppearance` → блок-мета (`"vu"`=viewMode+userSettingID, `"u"`=только userSettingID, `"v"`, `""`); `itemsViewMode`/`itemsUserSettingID` → `true`; `itemsUserSettingPresentation` → подпись items-уровня (`"Текст"` | `{ru,en}`, по форме значения как presentation). Если контейнер несёт собственный `userSettingPresentation` (кастомная подпись настройки), значение — объект `{ meta: "u", presentation: "Текст" | {ru,en} }` (presentation по форме значения: строка → `xs:string`, объект → `LocalStringType`). Компилятор эмитит ТОЛЬКО указанные части (контент берёт из `filter`/`order`/`conditionalAppearance`). Нет ключа → полный каноничный скелет. Пустой объект `{}` → self-closing `` (оригинал без скелета). Декомпилятор пишет дескриптор только для отклонений от канона | #### parameters — параметры схемы дин-списка