mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-06-14 18:04:58 +03:00
feat(form-decompile,form-compile): Table headerHeight/footerHeight/currentRowUse + форм. conversationsRepresentation (pass-through)
Раундтрип терял 4 свойства (категория Table-скаляры + форм-уровень): - Table <HeaderHeight>/<FooterHeight> (высота шапки/подвала в строках; ~35/~6 форм) - Table <CurrentRowUse> (использование текущей строки; ≠ одноимённое свойство команды, у которой свой путь захвата/эмиссии). Значения: DontUse/Use/SelectionPresentation/ SelectionPresentationAndChoice/Choice - форм-уровень <ConversationsRepresentation> (Auto/Show/DontShow; редкое) Все три Table-свойства были явно отложены в Emit-Table (комментарий о «строгом Table-XSD»). Корпусные данные показывают, что 1С эмитит те же теги в РАЗНЫХ позициях у разных форм → загрузчик толерантен к порядку детей Table (как и существующий компилятор с ранним DataPath). Размещены pass-through в Emit-Table (height-теги рядом с UseAlternationRowColor, CurrentRowUse у блока дин-списка); форм-уровень — generic Emit-Properties (авто-PascalCase). decompile (ps1): захват headerHeight/footerHeight/currentRowUse на Table; ConversationsRepresentation в KNOWN_FORM_PROPS. compile (ps1+py): эмиссия в emit_table. Верификация: таргет-раундтрип 4 форм → match (TOTAL diff lines 0); регресс form-compile 43/43 (ps1+py); 1С-cert кейса table (форма с тремя тегами грузится в платформу). spec обновлён. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# form-compile v1.125 — Compile 1C managed form from JSON or object metadata
|
||||
# form-compile v1.126 — Compile 1C managed form from JSON or object metadata
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[string]$JsonPath,
|
||||
@@ -3026,8 +3026,8 @@ $script:genericScalars = @(
|
||||
@{ Tag='Shortcut'; Key='shortcut'; Kind='value' }
|
||||
# Батч простых скаляров (input/radio/group/picDecoration/button): режим выбора незаполненного,
|
||||
# равная ширина колонок, выравнивание детей, масштаб/зум картинки, форма/положение картинки кнопки.
|
||||
# (Table HeaderHeight/FooterHeight/CurrentRowUse — НЕ здесь: строгий Table-XSD требует точной
|
||||
# позиции, generic-позиция ломает загрузку; отдельная задача в Emit-Table.)
|
||||
# (Table HeaderHeight/FooterHeight/CurrentRowUse — НЕ здесь, а в Emit-Table: pass-through,
|
||||
# 1С толерантна к порядку детей Table — в корпусе те же теги встречаются в разных позициях.)
|
||||
@{ Tag='IncompleteChoiceMode'; Key='incompleteChoiceMode'; Kind='value' }
|
||||
@{ Tag='EqualColumnsWidth'; Key='equalColumnsWidth'; Kind='bool' }
|
||||
@{ Tag='ChildrenAlign'; Key='childrenAlign'; Kind='value' }
|
||||
@@ -4305,6 +4305,9 @@ function Emit-Table {
|
||||
if ($el.multipleChoice -eq $true) { X "$inner<MultipleChoice>true</MultipleChoice>" }
|
||||
if ($el.searchOnInput) { X "$inner<SearchOnInput>$($el.searchOnInput)</SearchOnInput>" }
|
||||
if ($null -ne $el.markIncomplete) { X "$inner<AutoMarkIncomplete>$(if ($el.markIncomplete){'true'}else{'false'})</AutoMarkIncomplete>" }
|
||||
# Высота шапки/подвала в строках (pass-through; 1С толерантна к порядку детей Table)
|
||||
if ($null -ne $el.headerHeight) { X "$inner<HeaderHeight>$($el.headerHeight)</HeaderHeight>" }
|
||||
if ($null -ne $el.footerHeight) { X "$inner<FooterHeight>$($el.footerHeight)</FooterHeight>" }
|
||||
if ($el.useAlternationRowColor -eq $true) { X "$inner<UseAlternationRowColor>true</UseAlternationRowColor>" }
|
||||
if ($el.selectionMode) { X "$inner<SelectionMode>$($el.selectionMode)</SelectionMode>" }
|
||||
if ($el.rowSelectionMode) { X "$inner<RowSelectionMode>$($el.rowSelectionMode)</RowSelectionMode>" }
|
||||
@@ -4315,6 +4318,8 @@ function Emit-Table {
|
||||
if ($el.rowPictureDataPath) { X "$inner<RowPictureDataPath>$($el.rowPictureDataPath)</RowPictureDataPath>" }
|
||||
# RowsPicture — та же конвенция, что ValuesPicture (дефолт LoadTransparent=false; abs/TransparentPixel)
|
||||
Emit-PictureRef -val $el.rowsPicture -picTag 'RowsPicture' -indent $inner
|
||||
# Использование текущей строки таблицы (pass-through; в корпусе соседствует с блоком дин-списка)
|
||||
if ($el.currentRowUse) { X "$inner<CurrentRowUse>$($el.currentRowUse)</CurrentRowUse>" }
|
||||
# Блок свойств дин-список-таблицы (помечена эвристикой 11b.4)
|
||||
if ($el.PSObject.Properties["_dynList"] -and $el._dynList) { Emit-DynListTableBlock -el $el -indent $inner }
|
||||
if ($el.viewStatusLocation) { X "$inner<ViewStatusLocation>$($el.viewStatusLocation)</ViewStatusLocation>" }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# form-compile v1.125 — Compile 1C managed form from JSON or object metadata
|
||||
# form-compile v1.126 — Compile 1C managed form from JSON or object metadata
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import copy
|
||||
@@ -4029,6 +4029,11 @@ def emit_table(lines, el, name, eid, indent):
|
||||
lines.append(f'{inner}<SearchOnInput>{el["searchOnInput"]}</SearchOnInput>')
|
||||
if el.get('markIncomplete') is not None:
|
||||
lines.append(f'{inner}<AutoMarkIncomplete>{"true" if el["markIncomplete"] else "false"}</AutoMarkIncomplete>')
|
||||
# Высота шапки/подвала в строках (pass-through; 1С толерантна к порядку детей Table)
|
||||
if el.get('headerHeight') is not None:
|
||||
lines.append(f'{inner}<HeaderHeight>{el["headerHeight"]}</HeaderHeight>')
|
||||
if el.get('footerHeight') is not None:
|
||||
lines.append(f'{inner}<FooterHeight>{el["footerHeight"]}</FooterHeight>')
|
||||
if el.get('useAlternationRowColor') is True:
|
||||
lines.append(f'{inner}<UseAlternationRowColor>true</UseAlternationRowColor>')
|
||||
if el.get('selectionMode'):
|
||||
@@ -4047,6 +4052,9 @@ def emit_table(lines, el, name, eid, indent):
|
||||
lines.append(f'{inner}<RowPictureDataPath>{el["rowPictureDataPath"]}</RowPictureDataPath>')
|
||||
# RowsPicture — та же конвенция, что ValuesPicture (дефолт LoadTransparent=false; abs/TransparentPixel)
|
||||
emit_picture_ref(lines, el.get('rowsPicture'), 'RowsPicture', inner)
|
||||
# Использование текущей строки таблицы (pass-through; в корпусе соседствует с блоком дин-списка)
|
||||
if el.get('currentRowUse'):
|
||||
lines.append(f'{inner}<CurrentRowUse>{el["currentRowUse"]}</CurrentRowUse>')
|
||||
# Блок свойств дин-список-таблицы (помечена эвристикой)
|
||||
if el.get('_dynList'):
|
||||
emit_dynlist_table_block(lines, el, inner)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# form-decompile v0.99 — Decompile 1C managed Form.xml to JSON DSL (draft)
|
||||
# form-decompile v1.00 — Decompile 1C managed Form.xml to JSON DSL (draft)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
# ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью.
|
||||
param(
|
||||
@@ -1761,6 +1761,11 @@ function Decompile-Element {
|
||||
if ((Get-Child $node 'Footer') -eq 'true') { $obj['footer'] = $true }
|
||||
# Высота в строках — отдельный ключ heightInTableRows (≠ height = <Height>, его ловит Add-Layout)
|
||||
$htr = Get-Child $node 'HeightInTableRows'; if ($htr) { $obj['heightInTableRows'] = [int]$htr }
|
||||
# Высота шапки/подвала таблицы в строках (pass-through; компилятор эмитит в Emit-Table)
|
||||
$hh = Get-Child $node 'HeaderHeight'; if ($null -ne $hh) { $obj['headerHeight'] = [int]$hh }
|
||||
$fh = Get-Child $node 'FooterHeight'; if ($null -ne $fh) { $obj['footerHeight'] = [int]$fh }
|
||||
# Использование текущей строки (Table-уровень; ≠ command-level CurrentRowUse) — pass-through
|
||||
$cru = Get-Child $node 'CurrentRowUse'; if ($cru) { $obj['currentRowUse'] = $cru }
|
||||
# CommandBarLocation: для дин-список-таблицы компилятор авто-инжектит "None" → инвертируем
|
||||
# (нет тега → суппресс-маркер ""; "None" → опускаем = авто-дефолт; иначе → захват).
|
||||
$cbl = Get-Child $node 'CommandBarLocation'
|
||||
@@ -2187,7 +2192,7 @@ $titleNode = $root.SelectSingleNode("lf:Title", $ns)
|
||||
if ($titleNode) { $t = Get-LangText $titleNode; if ($null -ne $t) { $dsl['title'] = $t } }
|
||||
|
||||
# properties (прямые скаляры под <Form>, PascalCase → camelCase)
|
||||
$KNOWN_FORM_PROPS = @('AutoTitle','ReportResult','DetailsData','ReportFormType','AutoShowState','ReportResultViewMode','ViewModeApplicationOnSetReportResult','WindowOpeningMode','CommandBarLocation','SaveDataInSettings','AutoSaveDataInSettings','AutoTime','UsePostingMode','RepostOnWrite','AutoURL','AutoFillCheck','Customizable','EnterKeyBehavior','VerticalScroll','Width','Height','Group','UseForFoldersAndItems','SaveWindowSettings','ScalingMode','VerticalSpacing','VariantAppearance','ShowCloseButton','HorizontalAlign','ChildrenAlign','ShowTitle')
|
||||
$KNOWN_FORM_PROPS = @('AutoTitle','ReportResult','DetailsData','ReportFormType','AutoShowState','ReportResultViewMode','ViewModeApplicationOnSetReportResult','WindowOpeningMode','CommandBarLocation','SaveDataInSettings','AutoSaveDataInSettings','AutoTime','UsePostingMode','RepostOnWrite','AutoURL','AutoFillCheck','Customizable','EnterKeyBehavior','VerticalScroll','Width','Height','Group','UseForFoldersAndItems','SaveWindowSettings','ScalingMode','VerticalSpacing','VariantAppearance','ShowCloseButton','HorizontalAlign','ChildrenAlign','ShowTitle','ConversationsRepresentation')
|
||||
$props = [ordered]@{}
|
||||
foreach ($pn in $KNOWN_FORM_PROPS) {
|
||||
$v = Get-Child $root $pn
|
||||
|
||||
@@ -78,6 +78,7 @@
|
||||
| `horizontalAlign` | `<HorizontalAlign>` | `Left`, `Center`, `Right` — горизонтальное выравнивание формы |
|
||||
| `childrenAlign` | `<ChildrenAlign>` | Выравнивание элементов/заголовков (`ItemsLeftTitlesLeft`, `ItemsRightTitlesLeft`, `None`, …) |
|
||||
| `showTitle` | `<ShowTitle>` | `true` / `false` — показывать заголовок формы |
|
||||
| `conversationsRepresentation` | `<ConversationsRepresentation>` | `Auto`, `Show`, `DontShow` — отображение панели обсуждений; pass-through (редкое) |
|
||||
|
||||
Нераспознанные ключи преобразуются с автоматическим PascalCase (первая буква в верхний регистр).
|
||||
|
||||
@@ -560,6 +561,9 @@ companion-панели с собственным контентом. Оба не
|
||||
| `heightInTableRows` | int | Высота в строках (`<HeightInTableRows>`) — отдельное свойство от `height`; таблица может нести оба |
|
||||
| `header` | bool | Показывать шапку |
|
||||
| `footer` | bool | Показывать подвал |
|
||||
| `headerHeight` | int | Высота шапки в строках (`<HeaderHeight>`); pass-through (редкое, ~35 форм в корпусе) |
|
||||
| `footerHeight` | int | Высота подвала в строках (`<FooterHeight>`); pass-through (редкое, ~6 форм) |
|
||||
| `currentRowUse` | string | Использование текущей строки таблицы (`<CurrentRowUse>`): `DontUse`, `Use`, `SelectionPresentation`, `SelectionPresentationAndChoice`, `Choice`; pass-through (≠ одноимённое свойство команды) |
|
||||
| `commandBarLocation` | string | `None`, `Top`, `Bottom`, `Auto` |
|
||||
| `searchStringLocation` | string | `None`, `Top`, `Bottom`, `CommandBar`, `Auto` |
|
||||
| `viewStatusLocation` | string | `None`, `Top`, `Bottom`, `Auto` |
|
||||
|
||||
+3
@@ -18,6 +18,9 @@
|
||||
<MultipleChoice>true</MultipleChoice>
|
||||
<SearchOnInput>Use</SearchOnInput>
|
||||
<AutoMarkIncomplete>true</AutoMarkIncomplete>
|
||||
<HeaderHeight>2</HeaderHeight>
|
||||
<FooterHeight>1</FooterHeight>
|
||||
<CurrentRowUse>SelectionPresentationAndChoice</CurrentRowUse>
|
||||
<ViewStatusLocation>None</ViewStatusLocation>
|
||||
<SearchControlLocation>None</SearchControlLocation>
|
||||
<CommandSet>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"input": {
|
||||
"title": "Просмотр данных",
|
||||
"elements": [
|
||||
{ "table": "Данные", "path": "Данные", "changeRowSet": true, "titleLocation": "top", "height": 80, "heightInTableRows": 5, "autofill": true, "multipleChoice": true, "searchOnInput": "Use", "markIncomplete": true, "settingsNamedItemDetailedRepresentation": false, "heightControlVariant": "UseHeightInTableRows", "maxRowsCount": 5, "autoMaxRowsCount": false,
|
||||
{ "table": "Данные", "path": "Данные", "changeRowSet": true, "titleLocation": "top", "height": 80, "heightInTableRows": 5, "headerHeight": 2, "footerHeight": 1, "currentRowUse": "SelectionPresentationAndChoice", "autofill": true, "multipleChoice": true, "searchOnInput": "Use", "markIncomplete": true, "settingsNamedItemDetailedRepresentation": false, "heightControlVariant": "UseHeightInTableRows", "maxRowsCount": 5, "autoMaxRowsCount": false,
|
||||
"viewStatusLocation": "None", "searchControlLocation": "None",
|
||||
"excludedCommands": ["Add", "Delete", "MoveUp", "MoveDown"],
|
||||
"commandBar": { "autofill": false, "children": [
|
||||
|
||||
Reference in New Issue
Block a user