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): единая ML-text форма для заголовков декораций (Label/Picture) — переиспользование Resolve-MLFormatted
Заголовок декорации — formatted-aware текст (как extendedTooltip). Раньше LabelDecoration
нёс formatted отдельным sibling-ключом, PictureDecoration терял атрибут formatted вовсе
(эмитил голый <Title> через generic Emit-Title). Теперь оба идут через общий
Emit-DecorationTitle → Resolve-MLFormatted (та же единая ML-text форма, что у extendedTooltip):
- title декорации: строка (formatted авто-детектится по разметке) / {ru,en} / {text, formatted}.
- атрибут <Title formatted="…"> эмитится ВСЕГДА (специфика декораций); для обычных элементов
Emit-Title остаётся без formatted (formatted — только у декораций, подтверждено корпусом:
LabelDecoration 6568 + PictureDecoration 2, прочие 0).
- back-compat: sibling-ключ formatted принимается как override авто-детекта; компилятор-вывод
LabelDecoration не изменился.
Декомпилятор (v0.27): декорации захватывают title через Get-MLFormattedValue (гибрид);
sibling formatted больше не выводится (форматированные обычно становятся просто строкой
с markup внутри). Компилятор (ps1+py v1.45): Emit-DecorationTitle для Label+Picture.
Валидация: LabelDecoration formatted round-trip CLEAN; PictureDecoration Title-formatted
закрыт (29→0); регресс 33/33 ps+py; py==ps1; harness 8202→8144. Spec обновлён.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# form-compile v1.44 — Compile 1C managed form from JSON or object metadata
|
||||
# form-compile v1.45 — Compile 1C managed form from JSON or object metadata
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[string]$JsonPath,
|
||||
@@ -2950,23 +2950,31 @@ function Emit-Radio {
|
||||
X "$indent</RadioButtonField>"
|
||||
}
|
||||
|
||||
# Заголовок декорации (Label/Picture): formatted-aware <Title> через единую ML-text форму
|
||||
# (reuse Resolve-MLFormatted, как у extendedTooltip). Атрибут formatted эмитится ВСЕГДА
|
||||
# (специфика декораций). Sibling-ключ `formatted` — back-compat override авто-детекта.
|
||||
function Emit-DecorationTitle {
|
||||
param($el, [string]$name, [string]$indent, [switch]$auto)
|
||||
$hasKey = $null -ne $el.PSObject.Properties['title']
|
||||
$titleVal = if ($hasKey) { $el.title } elseif ($auto -and $name) { Title-FromName -name $name } else { $null }
|
||||
if ($titleVal) {
|
||||
$r = Resolve-MLFormatted $titleVal
|
||||
$fmt = if ($null -ne $el.PSObject.Properties['formatted']) { [bool]$el.formatted } else { $r.formatted }
|
||||
X "$indent<Title formatted=`"$(if ($fmt) { 'true' } else { 'false' })`">"
|
||||
Emit-MLItems -val $r.text -indent "$indent`t"
|
||||
X "$indent</Title>"
|
||||
}
|
||||
if ($el.tooltip) { Emit-MLText -tag "ToolTip" -text $el.tooltip -indent $indent }
|
||||
if ($el.tooltipRepresentation) { X "$indent<ToolTipRepresentation>$($el.tooltipRepresentation)</ToolTipRepresentation>" }
|
||||
}
|
||||
|
||||
function Emit-Label {
|
||||
param($el, [string]$name, [int]$id, [string]$indent)
|
||||
|
||||
X "$indent<LabelDecoration name=`"$name`" id=`"$id`">"
|
||||
$inner = "$indent`t"
|
||||
|
||||
$hasTitleKey = $null -ne $el.PSObject.Properties['title']
|
||||
$labelTitle = if ($hasTitleKey) { $el.title } else { Title-FromName -name $name }
|
||||
if ($labelTitle) {
|
||||
# formatted — независимое свойство (НЕ выводится из hyperlink): ссылка может быть не-форматированной и наоборот.
|
||||
$formatted = if ($el.formatted -eq $true) { "true" } else { "false" }
|
||||
X "$inner<Title formatted=`"$formatted`">"
|
||||
Emit-MLItems -val $labelTitle -indent "$inner`t"
|
||||
X "$inner</Title>"
|
||||
}
|
||||
if ($el.tooltip) { Emit-MLText -tag "ToolTip" -text $el.tooltip -indent $inner }
|
||||
if ($el.tooltipRepresentation) { X "$inner<ToolTipRepresentation>$($el.tooltipRepresentation)</ToolTipRepresentation>" }
|
||||
Emit-DecorationTitle -el $el -name $name -indent $inner -auto
|
||||
|
||||
Emit-CommonFlags -el $el -indent $inner
|
||||
|
||||
@@ -3297,7 +3305,7 @@ function Emit-PictureDecoration {
|
||||
X "$indent<PictureDecoration name=`"$name`" id=`"$id`">"
|
||||
$inner = "$indent`t"
|
||||
|
||||
Emit-Title -el $el -name $name -indent $inner
|
||||
Emit-DecorationTitle -el $el -name $name -indent $inner
|
||||
Emit-CommonFlags -el $el -indent $inner
|
||||
|
||||
if ($el.picture -or $el.src) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# form-compile v1.44 — Compile 1C managed form from JSON or object metadata
|
||||
# form-compile v1.45 — Compile 1C managed form from JSON or object metadata
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import copy
|
||||
@@ -2639,21 +2639,29 @@ def emit_radio_button_field(lines, el, name, eid, indent):
|
||||
lines.append(f'{indent}</RadioButtonField>')
|
||||
|
||||
|
||||
# Заголовок декорации (Label/Picture): formatted-aware <Title> через единую ML-text форму
|
||||
# (reuse resolve_ml_formatted, как у extendedTooltip). Sibling-ключ formatted — back-compat override.
|
||||
def emit_decoration_title(lines, el, name, indent, auto=False):
|
||||
has_key = 'title' in el
|
||||
title_val = el['title'] if has_key else (title_from_name(name) if (auto and name) else None)
|
||||
if title_val:
|
||||
text, fmt = resolve_ml_formatted(title_val)
|
||||
if 'formatted' in el:
|
||||
fmt = bool(el['formatted'])
|
||||
lines.append(f'{indent}<Title formatted="{"true" if fmt else "false"}">')
|
||||
emit_ml_items(lines, f'{indent}\t', text)
|
||||
lines.append(f'{indent}</Title>')
|
||||
if el.get('tooltip'):
|
||||
emit_mltext(lines, indent, 'ToolTip', el['tooltip'])
|
||||
if el.get('tooltipRepresentation'):
|
||||
lines.append(f'{indent}<ToolTipRepresentation>{el["tooltipRepresentation"]}</ToolTipRepresentation>')
|
||||
|
||||
|
||||
def emit_label(lines, el, name, eid, indent):
|
||||
lines.append(f'{indent}<LabelDecoration name="{name}" id="{eid}">')
|
||||
inner = f'{indent}\t'
|
||||
|
||||
label_title = el['title'] if 'title' in el else title_from_name(name)
|
||||
if label_title:
|
||||
# formatted — независимое свойство (НЕ выводится из hyperlink).
|
||||
formatted = 'true' if el.get('formatted') is True else 'false'
|
||||
lines.append(f'{inner}<Title formatted="{formatted}">')
|
||||
emit_ml_items(lines, f'{inner}\t', label_title)
|
||||
lines.append(f'{inner}</Title>')
|
||||
if el.get('tooltip'):
|
||||
emit_mltext(lines, inner, 'ToolTip', el['tooltip'])
|
||||
if el.get('tooltipRepresentation'):
|
||||
lines.append(f'{inner}<ToolTipRepresentation>{el["tooltipRepresentation"]}</ToolTipRepresentation>')
|
||||
emit_decoration_title(lines, el, name, inner, auto=True)
|
||||
|
||||
emit_common_flags(lines, el, inner)
|
||||
|
||||
@@ -2971,7 +2979,7 @@ def emit_picture_decoration(lines, el, name, eid, indent):
|
||||
lines.append(f'{indent}<PictureDecoration name="{name}" id="{eid}">')
|
||||
inner = f'{indent}\t'
|
||||
|
||||
emit_title(lines, el, name, inner)
|
||||
emit_decoration_title(lines, el, name, inner)
|
||||
emit_common_flags(lines, el, inner)
|
||||
|
||||
if el.get('picture') or el.get('src'):
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# form-decompile v0.26 — Decompile 1C managed Form.xml to JSON DSL (draft)
|
||||
# form-decompile v0.27 — Decompile 1C managed Form.xml to JSON DSL (draft)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
# ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью.
|
||||
param(
|
||||
@@ -951,9 +951,9 @@ function Decompile-Element {
|
||||
$obj[$key] = $name
|
||||
Add-CommonProps $obj $node $name
|
||||
if ((Get-Child $node 'Hyperlink') -eq 'true') { $obj['hyperlink'] = $true }
|
||||
# formatted — атрибут <Title formatted="…">, НЕЗАВИСИМ от hyperlink (true → ключ, false → опускаем)
|
||||
# title декорации — единая ML-text форма с авто-детектом formatted (как extendedTooltip)
|
||||
$tiNode = $node.SelectSingleNode("lf:Title", $ns)
|
||||
if ($tiNode -and $tiNode.GetAttribute('formatted') -eq 'true') { $obj['formatted'] = $true }
|
||||
if ($tiNode) { $tv = Get-MLFormattedValue $tiNode; if ($null -ne $tv) { $obj['title'] = $tv } }
|
||||
}
|
||||
'LabelField' {
|
||||
$obj[$key] = $name
|
||||
@@ -967,6 +967,9 @@ function Decompile-Element {
|
||||
'PictureDecoration' {
|
||||
$obj[$key] = $name
|
||||
Add-CommonProps $obj $node $name
|
||||
# title декорации — единая ML-text форма с formatted (атрибут <Title formatted> у PictureDecoration)
|
||||
$tiNode = $node.SelectSingleNode("lf:Title", $ns)
|
||||
if ($tiNode) { $tv = Get-MLFormattedValue $tiNode; if ($null -ne $tv) { $obj['title'] = $tv } }
|
||||
$ref = $node.SelectSingleNode("lf:Picture/xr:Ref", $ns); if ($ref) { $obj['src'] = $ref.InnerText }
|
||||
$lt = $node.SelectSingleNode("lf:Picture/xr:LoadTransparent", $ns); if ($lt -and $lt.InnerText -eq 'true') { $obj['loadTransparent'] = $true }
|
||||
if ((Get-Child $node 'Hyperlink') -eq 'true') { $obj['hyperlink'] = $true }
|
||||
|
||||
@@ -291,9 +291,9 @@
|
||||
|
||||
| Свойство | Тип | Описание |
|
||||
|----------|-----|----------|
|
||||
| `title` | string | Текст надписи |
|
||||
| `title` | string/object | Текст надписи. Единая ML-text форма (см. §4.1): строка / `{ru,en}` / `{text, formatted}`. У декораций `<Title>` всегда несёт атрибут `formatted` (авто-детект по разметке) |
|
||||
| `hyperlink` | bool | Режим гиперссылки |
|
||||
| `formatted` | bool | Форматированный текст (`<Title formatted="true">`). **Независим от `hyperlink`** — выводится только при `true` |
|
||||
| `formatted` | bool | **Back-compat**: явный override авто-детекта formatted (раньше — отдельный ключ). Предпочтительно — форма `title: {text, formatted}` |
|
||||
| `width` | int | Ширина |
|
||||
| `height` | int | Высота |
|
||||
| `autoMaxWidth` | bool | Автомаксимальная ширина |
|
||||
|
||||
Reference in New Issue
Block a user