feat(form-decompile,form-compile): общие свойства элемента DefaultItem/FileDragMode/EnableStartDrag/SkipOnInput (кластер generic element props)

Эти свойства — общие для любого типа элемента (таблица, поле, надпись, картинка,
кнопка), а не специфичны для таблицы. Раньше обрабатывались только в дин-список-блоке
Table → терялись на PictureDecoration/PictureField/LabelField/InputField/Button.

Перенесены в общий Emit-Layout/Add-Layout (универсальны — 17 вызовов компилятора,
один вызов декомпилятора на каждый элемент):
- DefaultItem (элемент по умолчанию), EnableStartDrag, FileDragMode — захват при наличии.
- SkipOnInput — теперь эмитится явное значение, включая false (раньше только true);
  декомпилятор захватывает фактическое значение.
- Вынесены в helper Emit-CommonElementProps; убраны дубли из дин-список-блока Table
  (useAlternationRowColor/initialTreeView остаются table-specific) и из Emit-Table
  (enableStartDrag).
Зеркало в form-compile.py идентично (py==ps1 проверено).

Валидация: FileDragMode/DefaultItem/EnableStartDrag — 0 LOST / 0 ADDED (полностью
закрыты на всех типах); SkipOnInput 141→37 (остаток — companion/nested-cmdbar кнопки,
редундантный false, в BACKLOG); регресс 33/33 ps+py; сертификация в 1С PASS; harness
8300→7971 (−329), 0 fail, match 7→8.

Spec: defaultItem/enableStartDrag/fileDragMode/skipOnInput → раздел 4.1 (общие свойства).
В BACKLOG: хвост SkipOnInput на companion + мис-атрибуция дубликатов в harness.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-06-06 16:16:18 +03:00
parent 1d158e3218
commit a9e1ab64c8
5 changed files with 50 additions and 26 deletions
@@ -1,4 +1,4 @@
# form-compile v1.40 — Compile 1C managed form from JSON or object metadata
# form-compile v1.41 — Compile 1C managed form from JSON or object metadata
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[string]$JsonPath,
@@ -2405,9 +2405,21 @@ function Emit-CommonFlags {
# историческим выводом input/label, чтобы не сдвигать существующие снапшоты.
# -skipHeight: для Table (height → HeightInTableRows, эмитится в Emit-Table).
# -multiLineDefault: input без явного autoMaxWidth при multiLine → AutoMaxWidth=false.
# Общие свойства элемента (любой тип, включая Button/cmdBar): default/skip/drag.
function Emit-CommonElementProps {
param($el, [string]$indent)
if ($el.defaultItem -eq $true) { X "$indent<DefaultItem>true</DefaultItem>" }
if ($el.PSObject.Properties['skipOnInput'] -and $null -ne $el.skipOnInput) {
$siv = if ($el.skipOnInput -eq $true) { 'true' } else { 'false' }
X "$indent<SkipOnInput>$siv</SkipOnInput>"
}
if ($el.enableStartDrag -eq $true) { X "$indent<EnableStartDrag>true</EnableStartDrag>" }
if ($el.fileDragMode) { X "$indent<FileDragMode>$($el.fileDragMode)</FileDragMode>" }
}
function Emit-Layout {
param($el, [string]$indent, [switch]$skipHeight, [bool]$multiLineDefault = $false)
if ($el.skipOnInput -eq $true) { X "$indent<SkipOnInput>true</SkipOnInput>" }
Emit-CommonElementProps -el $el -indent $indent
$amwExplicit = ($el.PSObject.Properties.Name -contains 'autoMaxWidth')
if ($amwExplicit) {
if ($el.autoMaxWidth -eq $false) { X "$indent<AutoMaxWidth>false</AutoMaxWidth>" }
@@ -2960,10 +2972,9 @@ function Emit-LabelField {
# DSL-ключ переопределяет; декомпилятор инвертирует (опускает значения = дефолту).
function Emit-DynListTableBlock {
param($el, [string]$indent)
# Group B (условные опц.): defaultItem / useAlternationRowColor / fileDragMode
if ($el.defaultItem -eq $true) { X "$indent<DefaultItem>true</DefaultItem>" }
# UseAlternationRowColor — специфично для list-таблицы (defaultItem/fileDragMode/
# enableStartDrag — общие, эмитятся в Emit-Layout)
if ($el.useAlternationRowColor -eq $true) { X "$indent<UseAlternationRowColor>true</UseAlternationRowColor>" }
if ($el.fileDragMode) { X "$indent<FileDragMode>$($el.fileDragMode)</FileDragMode>" }
# Group A (гарант. блок, n=5079): дефолт + override
$ar = if ($el.autoRefresh -eq $true) { "true" } else { "false" }
X "$indent<AutoRefresh>$ar</AutoRefresh>"
@@ -3019,7 +3030,6 @@ function Emit-Table {
}
if ($el.choiceMode -eq $true) { X "$inner<ChoiceMode>true</ChoiceMode>" }
if ($el.initialTreeView) { X "$inner<InitialTreeView>$($el.initialTreeView)</InitialTreeView>" }
if ($el.enableStartDrag -eq $true) { X "$inner<EnableStartDrag>true</EnableStartDrag>" }
if ($el.enableDrag -eq $true) { X "$inner<EnableDrag>true</EnableDrag>" }
if ($el.rowPictureDataPath) { X "$inner<RowPictureDataPath>$($el.rowPictureDataPath)</RowPictureDataPath>" }
if ($el.rowsPicture) {
@@ -3143,6 +3153,7 @@ function Emit-Button {
X "$indent<Button name=`"$name`" id=`"$id`">"
$inner = "$indent`t"
# (общие свойства — через Emit-Layout ниже; отдельный вызов был бы двойной эмиссией)
# Type — context-aware:
# Inside command bar (cmdBar/autoCmdBar/popup) only CommandBarButton/CommandBarHyperlink are valid.
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# form-compile v1.40 — Compile 1C managed form from JSON or object metadata
# form-compile v1.41 — Compile 1C managed form from JSON or object metadata
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
import copy
@@ -2043,13 +2043,25 @@ def emit_common_flags(lines, el, indent):
lines.append(f"{indent}<ReadOnly>true</ReadOnly>")
# Общие свойства элемента (любой тип, включая Button/cmdBar): default/skip/drag.
def emit_common_element_props(lines, el, indent):
if el.get('defaultItem') is True:
lines.append(f"{indent}<DefaultItem>true</DefaultItem>")
if 'skipOnInput' in el and el['skipOnInput'] is not None:
siv = 'true' if el['skipOnInput'] is True else 'false'
lines.append(f"{indent}<SkipOnInput>{siv}</SkipOnInput>")
if el.get('enableStartDrag') is True:
lines.append(f"{indent}<EnableStartDrag>true</EnableStartDrag>")
if el.get('fileDragMode'):
lines.append(f"{indent}<FileDragMode>{el['fileDragMode']}</FileDragMode>")
def emit_layout(lines, el, indent, skip_height=False, multi_line_default=False):
# Общие layout-свойства — применимы ко всем элементам. Порядок согласован
# с историческим выводом input/label, чтобы не сдвигать существующие снапшоты.
# skip_height: для Table (height → HeightInTableRows, эмитится в emit_table).
# multi_line_default: input без явного autoMaxWidth при multiLine → AutoMaxWidth=false.
if el.get('skipOnInput') is True:
lines.append(f"{indent}<SkipOnInput>true</SkipOnInput>")
emit_common_element_props(lines, el, indent)
if 'autoMaxWidth' in el:
if el.get('autoMaxWidth') is False:
lines.append(f"{indent}<AutoMaxWidth>false</AutoMaxWidth>")
@@ -2659,13 +2671,10 @@ def emit_label_field(lines, el, name, eid, indent):
# Блок свойств таблицы, привязанной к динамическому списку (Group A defaults + B/C).
def emit_dynlist_table_block(lines, el, indent):
# Group B (условные опц.)
if el.get('defaultItem') is True:
lines.append(f'{indent}<DefaultItem>true</DefaultItem>')
# UseAlternationRowColor — специфично для list-таблицы (defaultItem/fileDragMode/
# enableStartDrag — общие, эмитятся в emit_layout)
if el.get('useAlternationRowColor') is True:
lines.append(f'{indent}<UseAlternationRowColor>true</UseAlternationRowColor>')
if el.get('fileDragMode'):
lines.append(f'{indent}<FileDragMode>{el["fileDragMode"]}</FileDragMode>')
# Group A (гарант. блок): дефолт + override
ar = 'true' if el.get('autoRefresh') is True else 'false'
lines.append(f'{indent}<AutoRefresh>{ar}</AutoRefresh>')
@@ -2727,8 +2736,6 @@ def emit_table(lines, el, name, eid, indent):
lines.append(f'{inner}<ChoiceMode>true</ChoiceMode>')
if el.get('initialTreeView'):
lines.append(f'{inner}<InitialTreeView>{el["initialTreeView"]}</InitialTreeView>')
if el.get('enableStartDrag') is True:
lines.append(f'{inner}<EnableStartDrag>true</EnableStartDrag>')
if el.get('enableDrag') is True:
lines.append(f'{inner}<EnableDrag>true</EnableDrag>')
if el.get('rowPictureDataPath'):
@@ -2843,6 +2850,7 @@ def emit_page(lines, el, name, eid, indent):
def emit_button(lines, el, name, eid, indent, in_cmd_bar=False):
lines.append(f'{indent}<Button name="{name}" id="{eid}">')
inner = f'{indent}\t'
# (общие свойства — через emit_layout ниже; отдельный вызов был бы двойной эмиссией)
# Type — context-aware. Inside command bars (cmdBar/autoCmdBar/popup) only
# CommandBarButton/CommandBarHyperlink are valid; UsualButton/Hyperlink would be ignored.
@@ -1,4 +1,4 @@
# form-decompile v0.22 — Decompile 1C managed Form.xml to JSON DSL (draft)
# form-decompile v0.23 — Decompile 1C managed Form.xml to JSON DSL (draft)
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
# ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью.
param(
@@ -716,7 +716,11 @@ function Build-ConditionalAppearance {
# (<Height>); Table хранит высоту в строках (<HeightInTableRows>) и ловит её сам.
function Add-Layout {
param($obj, $node)
if ((Get-Child $node 'SkipOnInput') -eq 'true') { $obj['skipOnInput'] = $true }
# Общие свойства элемента (любой тип): default/drag/skip
if ((Get-Child $node 'DefaultItem') -eq 'true') { $obj['defaultItem'] = $true }
$soi = Get-Child $node 'SkipOnInput'; if ($null -ne $soi) { $obj['skipOnInput'] = ($soi -eq 'true') }
if ((Get-Child $node 'EnableStartDrag') -eq 'true') { $obj['enableStartDrag'] = $true }
$fdm = Get-Child $node 'FileDragMode'; if ($fdm) { $obj['fileDragMode'] = $fdm }
if ((Get-Child $node 'AutoMaxWidth') -eq 'false') { $obj['autoMaxWidth'] = $false }
$mw = Get-Child $node 'MaxWidth'; if ($mw) { $obj['maxWidth'] = [int]$mw }
if ((Get-Child $node 'AutoMaxHeight') -eq 'false') { $obj['autoMaxHeight'] = $false }
@@ -991,12 +995,10 @@ function Decompile-Element {
if ((Get-Child $node 'AllowRootChoice') -eq 'true') { $obj['allowRootChoice'] = $true }
$uodc = Get-Child $node 'UpdateOnDataChange'; if ($uodc -and $uodc -ne 'Auto') { $obj['updateOnDataChange'] = $uodc }
if ((Get-Child $node 'AllowGettingCurrentRowURL') -eq 'false') { $obj['allowGettingCurrentRowURL'] = $false }
# Group B (захват при наличии)
if ((Get-Child $node 'DefaultItem') -eq 'true') { $obj['defaultItem'] = $true }
# list-таблица: useAlternationRowColor/initialTreeView (defaultItem/enableStartDrag/
# fileDragMode — общие, ловятся в Add-Layout)
if ((Get-Child $node 'UseAlternationRowColor') -eq 'true') { $obj['useAlternationRowColor'] = $true }
$itv = Get-Child $node 'InitialTreeView'; if ($itv) { $obj['initialTreeView'] = $itv }
if ((Get-Child $node 'EnableStartDrag') -eq 'true') { $obj['enableStartDrag'] = $true }
$fdm = Get-Child $node 'FileDragMode'; if ($fdm) { $obj['fileDragMode'] = $fdm }
# Group C
$rpdp = Get-Child $node 'RowPictureDataPath'
if ($null -eq $rpdp) { $obj['rowPictureDataPath'] = '' }
+6 -3
View File
@@ -136,7 +136,12 @@
| `groupHorizontalAlign` | `<GroupHorizontalAlign>` | `Left`, `Center`, `Right` |
| `groupVerticalAlign` | `<GroupVerticalAlign>` | `Top`, `Center`, `Bottom` |
| `horizontalAlign` | `<HorizontalAlign>` | `Left`, `Center`, `Right` |
| `skipOnInput` | `<SkipOnInput>` | `true` |
| `skipOnInput` | `<SkipOnInput>` | `true`/`false` (эмитится явное значение, в т.ч. `false`) |
| `defaultItem` | `<DefaultItem>` | `true` (элемент активируется по умолчанию) |
| `enableStartDrag` | `<EnableStartDrag>` | `true` (разрешить начало перетаскивания) |
| `fileDragMode` | `<FileDragMode>` | `AsFile`/… (режим drag-n-drop файлов) |
> `defaultItem`/`enableStartDrag`/`fileDragMode`/`skipOnInput` — общие для любого типа элемента (таблица, поле, надпись, картинка, кнопка), не только таблицы.
### 4.2. События элемента и автоименование обработчиков
@@ -328,10 +333,8 @@
| Свойство | Тип | Умолчание | Описание |
|----------|-----|-----------|----------|
| `rowPictureDataPath` | string | `<Список>.DefaultPicture` (если есть осн. таблица) | Путь к картинке строки. `""` — подавить авто-вывод |
| `defaultItem` | bool | — | `<DefaultItem>` (элемент по умолчанию) |
| `useAlternationRowColor` | bool | — | Чередование цвета строк |
| `initialTreeView` | string | — | `ExpandTopLevel`, `ExpandAllLevels`, `NoExpand` |
| `enableStartDrag` / `fileDragMode` | bool / string | — | Перетаскивание; `fileDragMode` = `AsFile`/… |
| `autoRefresh` | bool | `false` | Автообновление |
| `autoRefreshPeriod` | int | `60` | Период автообновления, сек |
| `choiceFoldersAndItems` | string | `Items` | `Items`, `Folders`, `FoldersAndItems` |
@@ -13,7 +13,6 @@
<DataPath>Список</DataPath>
<CommandBarLocation>None</CommandBarLocation>
<InitialTreeView>ExpandTopLevel</InitialTreeView>
<EnableStartDrag>true</EnableStartDrag>
<EnableDrag>true</EnableDrag>
<RowPictureDataPath>Список.DefaultPicture</RowPictureDataPath>
<AutoRefresh>false</AutoRefresh>
@@ -30,6 +29,7 @@
<AllowRootChoice>false</AllowRootChoice>
<UpdateOnDataChange>Auto</UpdateOnDataChange>
<AllowGettingCurrentRowURL>true</AllowGettingCurrentRowURL>
<EnableStartDrag>true</EnableStartDrag>
<ContextMenu name="СписокКонтекстноеМеню" id="2"/>
<AutoCommandBar name="СписокКоманднаяПанель" id="3">
<Autofill>false</Autofill>