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): 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>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# form-compile v1.33 — Compile 1C managed form from JSON or object metadata
|
||||
# form-compile v1.34 — Compile 1C managed form from JSON or object metadata
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[string]$JsonPath,
|
||||
@@ -2551,6 +2551,7 @@ function Emit-LabelField {
|
||||
Emit-Title -el $el -name $name -indent $inner -auto:(-not $el.path)
|
||||
Emit-CommonFlags -el $el -indent $inner
|
||||
|
||||
if ($el.titleLocation) { X "$inner<TitleLocation>$(Map-TitleLoc "$($el.titleLocation)")</TitleLocation>" }
|
||||
if ($el.editMode) { X "$inner<EditMode>$($el.editMode)</EditMode>" }
|
||||
# ВНИМАНИЕ: у LabelField платформенный тег именно <Hiperlink> (опечатка 1С), не <Hyperlink>.
|
||||
if ($el.hyperlink -eq $true) { X "$inner<Hiperlink>true</Hiperlink>" }
|
||||
@@ -2579,6 +2580,7 @@ function Emit-Table {
|
||||
if ($el.representation) {
|
||||
X "$inner<Representation>$($el.representation)</Representation>"
|
||||
}
|
||||
if ($el.titleLocation) { X "$inner<TitleLocation>$(Map-TitleLoc "$($el.titleLocation)")</TitleLocation>" }
|
||||
if ($el.changeRowSet -eq $true) { X "$inner<ChangeRowSet>true</ChangeRowSet>" }
|
||||
if ($el.changeRowOrder -eq $true) { X "$inner<ChangeRowOrder>true</ChangeRowOrder>" }
|
||||
if ($el.height) { X "$inner<HeightInTableRows>$($el.height)</HeightInTableRows>" }
|
||||
@@ -2833,6 +2835,8 @@ function Emit-PictureField {
|
||||
Emit-Title -el $el -name $name -indent $inner
|
||||
Emit-CommonFlags -el $el -indent $inner
|
||||
|
||||
if ($el.titleLocation) { X "$inner<TitleLocation>$(Map-TitleLoc "$($el.titleLocation)")</TitleLocation>" }
|
||||
|
||||
# ValuesPicture — picture (collection) used to render the field's value.
|
||||
# Required for a Boolean-bound PictureField to actually show an icon.
|
||||
# loadTransparent emitted only when true (1С default is false).
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# form-compile v1.33 — Compile 1C managed form from JSON or object metadata
|
||||
# form-compile v1.34 — Compile 1C managed form from JSON or object metadata
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import copy
|
||||
@@ -2199,6 +2199,8 @@ def emit_label_field(lines, el, name, eid, indent):
|
||||
emit_title(lines, el, name, inner, auto=not el.get('path'))
|
||||
emit_common_flags(lines, el, inner)
|
||||
|
||||
if el.get('titleLocation'):
|
||||
lines.append(f'{inner}<TitleLocation>{map_title_loc(el["titleLocation"])}</TitleLocation>')
|
||||
if el.get('editMode'):
|
||||
lines.append(f'{inner}<EditMode>{el["editMode"]}</EditMode>')
|
||||
# ВНИМАНИЕ: у LabelField платформенный тег <Hiperlink> (опечатка 1С), не <Hyperlink>.
|
||||
@@ -2227,6 +2229,8 @@ def emit_table(lines, el, name, eid, indent):
|
||||
|
||||
if el.get('representation'):
|
||||
lines.append(f'{inner}<Representation>{el["representation"]}</Representation>')
|
||||
if el.get('titleLocation'):
|
||||
lines.append(f'{inner}<TitleLocation>{map_title_loc(el["titleLocation"])}</TitleLocation>')
|
||||
if el.get('changeRowSet') is True:
|
||||
lines.append(f'{inner}<ChangeRowSet>true</ChangeRowSet>')
|
||||
if el.get('changeRowOrder') is True:
|
||||
@@ -2465,6 +2469,9 @@ def emit_picture_field(lines, el, name, eid, indent):
|
||||
emit_title(lines, el, name, inner)
|
||||
emit_common_flags(lines, el, inner)
|
||||
|
||||
if el.get('titleLocation'):
|
||||
lines.append(f'{inner}<TitleLocation>{map_title_loc(el["titleLocation"])}</TitleLocation>')
|
||||
|
||||
# ValuesPicture \u2014 picture (collection) used to render the field's value.
|
||||
# Required for a Boolean-bound PictureField to actually show an icon.
|
||||
# loadTransparent emitted only when true (1\u0421 default is false).
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# form-decompile v0.13 — Decompile 1C managed Form.xml to JSON DSL (draft)
|
||||
# form-decompile v0.14 — Decompile 1C managed Form.xml to JSON DSL (draft)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
# ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью.
|
||||
param(
|
||||
@@ -401,6 +401,7 @@ function Decompile-Element {
|
||||
$obj[$key] = $name
|
||||
$dp = Get-Child $node 'DataPath'; if ($dp) { $obj['path'] = $dp }
|
||||
Add-CommonProps $obj $node $name
|
||||
$tl = Get-Child $node 'TitleLocation'; if ($tl) { $obj['titleLocation'] = $tl.ToLower() }
|
||||
$em = Get-Child $node 'EditMode'; if ($em) { $obj['editMode'] = $em }
|
||||
# LabelField: тег <Hiperlink> (опечатка платформы), не <Hyperlink>
|
||||
if ((Get-Child $node 'Hiperlink') -eq 'true') { $obj['hyperlink'] = $true }
|
||||
@@ -416,6 +417,7 @@ function Decompile-Element {
|
||||
$obj[$key] = $name
|
||||
$dp = Get-Child $node 'DataPath'; if ($dp) { $obj['path'] = $dp }
|
||||
Add-CommonProps $obj $node $name
|
||||
$tl = Get-Child $node 'TitleLocation'; if ($tl) { $obj['titleLocation'] = $tl.ToLower() }
|
||||
$ref = $node.SelectSingleNode("lf:ValuesPicture/xr:Ref", $ns); if ($ref) { $obj['valuesPicture'] = $ref.InnerText }
|
||||
}
|
||||
'CalendarField' {
|
||||
@@ -433,6 +435,7 @@ function Decompile-Element {
|
||||
$obj[$key] = $name
|
||||
$dp = Get-Child $node 'DataPath'; if ($dp) { $obj['path'] = $dp }
|
||||
Add-CommonProps $obj $node $name
|
||||
$tl = Get-Child $node 'TitleLocation'; if ($tl) { $obj['titleLocation'] = $tl.ToLower() }
|
||||
$rep = Get-Child $node 'Representation'; if ($rep) { $obj['representation'] = $rep }
|
||||
if ((Get-Child $node 'ChangeRowSet') -eq 'true') { $obj['changeRowSet'] = $true }
|
||||
if ((Get-Child $node 'ChangeRowOrder') -eq 'true') { $obj['changeRowOrder'] = $true }
|
||||
|
||||
@@ -115,6 +115,7 @@
|
||||
| `disabled` | bool | `true` → `<Enabled>false</Enabled>` |
|
||||
| `readOnly` | bool | `true` → `<ReadOnly>true</ReadOnly>` |
|
||||
| `events` | object | Обработчики событий: `{ "ИмяСобытия": "ИмяОбработчика" }` — тот же формат, что у событий формы (§3). Значение `null` → имя по конвенции (§4.2). См. §4.2 |
|
||||
| `titleLocation` | string | Расположение заголовка: `none`/`left`/`right`/`top`/`bottom`/`auto`. Эмитится при наличии (input, labelField, picField, table, calendar). У `check`/`radio` — особая семантика с умным дефолтом (см. их разделы) |
|
||||
|
||||
### 4.1a. Общие layout-свойства
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"title": "Поля ввода",
|
||||
"elements": [
|
||||
{ "input": "ОбычноеПоле", "path": "ОбычноеПоле", "title": "Обычное поле", "editMode": "EnterOnInput" },
|
||||
{ "labelField": "Ссылка", "path": "ОбычноеПоле", "hyperlink": true },
|
||||
{ "labelField": "Ссылка", "path": "ОбычноеПоле", "titleLocation": "left", "hyperlink": true },
|
||||
{ "input": "МногострочноеПоле", "path": "МногострочноеПоле", "multiLine": true, "height": 5, "title": "Комментарий" },
|
||||
{ "input": "ПолеПароля", "path": "ПолеПароля", "passwordMode": true, "title": "Пароль" },
|
||||
{ "input": "ПолеСКнопками", "path": "ПолеСКнопками", "choiceButton": true, "clearButton": true, "title": "Выбор" },
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"on": ["Selection"], "handlers": { "Selection": "ТаблицаДанныхВыбор" },
|
||||
"columns": [
|
||||
{ "input": "ТаблицаДанныхНоменклатура", "path": "ТаблицаДанных.Номенклатура" },
|
||||
{ "picField": "ТаблицаДанныхКартинка", "path": "ТаблицаДанных.Картинка", "valuesPicture": "StdPicture.Favorites", "loadTransparent": true },
|
||||
{ "picField": "ТаблицаДанныхКартинка", "path": "ТаблицаДанных.Картинка", "titleLocation": "none", "valuesPicture": "StdPicture.Favorites", "loadTransparent": true },
|
||||
{ "check": "ТаблицаДанныхКартинкаФлаг", "path": "ТаблицаДанных.Картинка", "title": "Флаг" }
|
||||
]}
|
||||
],
|
||||
|
||||
+1
@@ -23,6 +23,7 @@
|
||||
</InputField>
|
||||
<LabelField name="Ссылка" id="4">
|
||||
<DataPath>ОбычноеПоле</DataPath>
|
||||
<TitleLocation>Left</TitleLocation>
|
||||
<Hiperlink>true</Hiperlink>
|
||||
<ContextMenu name="СсылкаКонтекстноеМеню" id="5"/>
|
||||
<ExtendedTooltip name="СсылкаРасширеннаяПодсказка" id="6"/>
|
||||
|
||||
+1
@@ -45,6 +45,7 @@
|
||||
</InputField>
|
||||
<PictureField name="ТаблицаДанныхКартинка" id="16">
|
||||
<DataPath>ТаблицаДанных.Картинка</DataPath>
|
||||
<TitleLocation>None</TitleLocation>
|
||||
<ValuesPicture>
|
||||
<xr:Ref>StdPicture.Favorites</xr:Ref>
|
||||
<xr:LoadTransparent>true</xr:LoadTransparent>
|
||||
|
||||
+1
@@ -11,6 +11,7 @@
|
||||
<ChildItems>
|
||||
<Table name="Данные" id="1">
|
||||
<DataPath>Данные</DataPath>
|
||||
<TitleLocation>Top</TitleLocation>
|
||||
<ChangeRowSet>true</ChangeRowSet>
|
||||
<ViewStatusLocation>None</ViewStatusLocation>
|
||||
<SearchControlLocation>None</SearchControlLocation>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"input": {
|
||||
"title": "Просмотр данных",
|
||||
"elements": [
|
||||
{ "table": "Данные", "path": "Данные", "changeRowSet": true,
|
||||
{ "table": "Данные", "path": "Данные", "changeRowSet": true, "titleLocation": "top",
|
||||
"viewStatusLocation": "None", "searchControlLocation": "None",
|
||||
"excludedCommands": ["Add", "Delete", "MoveUp", "MoveDown"], "columns": [
|
||||
{ "input": "Дата", "path": "Данные.Дата" },
|
||||
|
||||
Reference in New Issue
Block a user