mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-07-23 21:21:04 +03:00
feat(form-decompile,form-compile): ExtendedTooltip own-content (объектная форма)
ExtendedTooltip — это LabelDecoration: может нести own-content (layout/оформление/
флаги/hyperlink) вместо/вместе с текстом. Объектная форма extendedTooltip:
{ text?, formatted?, width?, autoMaxWidth?, maxWidth?, height?, horizontalStretch?,
verticalAlign?, titleHeight?, hyperlink?, visible?, enabled?, textColor?, font?, … }.
Дизамбигуация от текст-формы (строка/ML/{text,formatted}) — по наличию структурного
ключа. Переиспользует Emit-Layout/Emit-Appearance/Emit-CommonFlags + Emit-GenericScalars.
Порядок: own-content ПЕРЕД Title (в корпусе layout-first 582 vs 10) — заодно убирает
шум атрибуции харнесса на многострочном контенте. Декомпилятор собирает объект
(Add-Layout/Add-GenericScalars/Add-Appearance/флаги/hyperlink), текст → .text;
текст-only остаётся строкой (обратная совместимость).
Форма WildberriesПереходРВБ: TOTAL 35→2 (остаток — отдельный rowsPicture
LoadTransparent). Зеркало py (байт-в-байт), кейс input-fields (own-content+текст и
width-only) сертифицирован в 1С. Регресс 39/39 ps1+py. Хвост: События компаньона
(нужно имя-обработчик) — отложено.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
fb3bce5811
commit
ea43522b5a
@@ -1,4 +1,4 @@
|
||||
# form-compile v1.80 — Compile 1C managed form from JSON or object metadata
|
||||
# form-compile v1.81 — Compile 1C managed form from JSON or object metadata
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[string]$JsonPath,
|
||||
@@ -2287,6 +2287,34 @@ function Emit-Events {
|
||||
X "$indent</Events>"
|
||||
}
|
||||
|
||||
# ExtendedTooltip — это LabelDecoration: может нести own-content (layout/оформление/флаги/hyperlink)
|
||||
# вместо/вместе с текстом. Признак структурированной формы: объект с любым НЕ-текстовым ключом
|
||||
# ({text,formatted} и языковые ключи {ru,en} → обычная текст-форма).
|
||||
$script:companionStructKeys = @(
|
||||
'width','autoMaxWidth','maxWidth','height','autoMaxHeight','maxHeight','verticalAlign','titleHeight',
|
||||
'horizontalStretch','verticalStretch','horizontalAlign','groupHorizontalAlign','groupVerticalAlign',
|
||||
'visible','hidden','enabled','disabled','hyperlink',
|
||||
'textColor','backColor','borderColor','font','border','цветтекста','цветфона','цветрамки','шрифт','рамка'
|
||||
)
|
||||
function Test-CompanionStructured {
|
||||
param($content)
|
||||
if (-not (($content -is [System.Collections.IDictionary]) -or ($content -is [System.Management.Automation.PSCustomObject]))) { return $false }
|
||||
foreach ($k in $script:companionStructKeys) {
|
||||
$present = if ($content -is [System.Collections.IDictionary]) { $content.Contains($k) } else { [bool]$content.PSObject.Properties[$k] }
|
||||
if ($present) { return $true }
|
||||
}
|
||||
return $false
|
||||
}
|
||||
|
||||
function Emit-CompanionTitle {
|
||||
param($content, [string]$indent)
|
||||
$r = Resolve-MLFormatted $content
|
||||
$fmt = if ($r.formatted) { 'true' } else { 'false' }
|
||||
X "$indent<Title formatted=`"$fmt`">"
|
||||
Emit-MLItems -val $r.text -indent "$indent`t"
|
||||
X "$indent</Title>"
|
||||
}
|
||||
|
||||
function Emit-Companion {
|
||||
param([string]$tag, [string]$name, [string]$indent, $content = $null)
|
||||
$id = New-Id
|
||||
@@ -2295,13 +2323,20 @@ function Emit-Companion {
|
||||
X "$indent<$tag name=`"$name`" id=`"$id`"/>"
|
||||
return
|
||||
}
|
||||
# Companion с контентом: <Title formatted="…"> (расширенная подсказка)
|
||||
$inner = "$indent`t"
|
||||
X "$indent<$tag name=`"$name`" id=`"$id`">"
|
||||
$r = Resolve-MLFormatted $content
|
||||
$fmt = if ($r.formatted) { 'true' } else { 'false' }
|
||||
X "$indent`t<Title formatted=`"$fmt`">"
|
||||
Emit-MLItems -val $r.text -indent "$indent`t`t"
|
||||
X "$indent`t</Title>"
|
||||
if (Test-CompanionStructured $content) {
|
||||
# структурированная форма (own-content). Порядок как у платформы: own-content (флаги/hyperlink/
|
||||
# layout/оформление) ПЕРЕД Title (в корпусе layout-first 582 vs 10).
|
||||
$txtPresent = if ($content -is [System.Collections.IDictionary]) { $content.Contains('text') } else { [bool]$content.PSObject.Properties['text'] }
|
||||
Emit-CommonFlags -el $content -indent $inner
|
||||
if ($content.hyperlink -eq $true) { X "$inner<Hyperlink>true</Hyperlink>" }
|
||||
Emit-Layout -el $content -indent $inner
|
||||
Emit-Appearance -el $content -indent $inner -profile 'decoration'
|
||||
if ($txtPresent) { Emit-CompanionTitle -content $content -indent $inner }
|
||||
} else {
|
||||
Emit-CompanionTitle -content $content -indent $inner
|
||||
}
|
||||
X "$indent</$tag>"
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# form-compile v1.80 — Compile 1C managed form from JSON or object metadata
|
||||
# form-compile v1.81 — Compile 1C managed form from JSON or object metadata
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import copy
|
||||
@@ -2296,17 +2296,42 @@ def resolve_ml_formatted(val):
|
||||
return val, _has_real_markup(val)
|
||||
|
||||
|
||||
# ExtendedTooltip — это LabelDecoration: own-content (layout/оформление/флаги/hyperlink) ±текст.
|
||||
# Признак структурированной формы: объект с любым НЕ-текстовым ключом ({text,formatted}/{ru,en} → текст).
|
||||
COMPANION_STRUCT_KEYS = {
|
||||
'width', 'autoMaxWidth', 'maxWidth', 'height', 'autoMaxHeight', 'maxHeight', 'verticalAlign', 'titleHeight',
|
||||
'horizontalStretch', 'verticalStretch', 'horizontalAlign', 'groupHorizontalAlign', 'groupVerticalAlign',
|
||||
'visible', 'hidden', 'enabled', 'disabled', 'hyperlink',
|
||||
'textColor', 'backColor', 'borderColor', 'font', 'border', 'цветтекста', 'цветфона', 'цветрамки', 'шрифт', 'рамка',
|
||||
}
|
||||
|
||||
|
||||
def emit_companion_title(lines, content, indent):
|
||||
text, fmt = resolve_ml_formatted(content)
|
||||
lines.append(f'{indent}<Title formatted="{"true" if fmt else "false"}">')
|
||||
emit_ml_items(lines, f'{indent}\t', text)
|
||||
lines.append(f'{indent}</Title>')
|
||||
|
||||
|
||||
def emit_companion(lines, tag, name, indent, content=None):
|
||||
cid = new_id()
|
||||
has_content = content is not None and not (isinstance(content, str) and content == '')
|
||||
if not has_content:
|
||||
lines.append(f'{indent}<{tag} name="{name}" id="{cid}"/>')
|
||||
return
|
||||
inner = f'{indent}\t'
|
||||
lines.append(f'{indent}<{tag} name="{name}" id="{cid}">')
|
||||
text, fmt = resolve_ml_formatted(content)
|
||||
lines.append(f'{indent}\t<Title formatted="{"true" if fmt else "false"}">')
|
||||
emit_ml_items(lines, f'{indent}\t\t', text)
|
||||
lines.append(f'{indent}\t</Title>')
|
||||
if isinstance(content, dict) and any(k in content for k in COMPANION_STRUCT_KEYS):
|
||||
# own-content ПЕРЕД Title (в корпусе layout-first 582 vs 10).
|
||||
emit_common_flags(lines, content, inner)
|
||||
if content.get('hyperlink') is True:
|
||||
lines.append(f'{inner}<Hyperlink>true</Hyperlink>')
|
||||
emit_layout(lines, content, inner)
|
||||
emit_appearance(lines, content, inner, 'decoration')
|
||||
if 'text' in content:
|
||||
emit_companion_title(lines, content, inner)
|
||||
else:
|
||||
emit_companion_title(lines, content, inner)
|
||||
lines.append(f'{indent}</{tag}>')
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# form-decompile v0.56 — Decompile 1C managed Form.xml to JSON DSL (draft)
|
||||
# form-decompile v0.57 — Decompile 1C managed Form.xml to JSON DSL (draft)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
# ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью.
|
||||
param(
|
||||
@@ -1599,9 +1599,30 @@ function Decompile-Element {
|
||||
}
|
||||
Add-Layout $obj $node
|
||||
Add-GenericScalars $obj $node
|
||||
# extendedTooltip: контент companion <ExtendedTooltip><Title> (любой элемент)
|
||||
$etTitle = $node.SelectSingleNode("lf:ExtendedTooltip/lf:Title", $ns)
|
||||
if ($etTitle) { $et = Get-MLFormattedValue $etTitle; if ($null -ne $et) { $obj['extendedTooltip'] = $et } }
|
||||
# extendedTooltip: companion <ExtendedTooltip> (это LabelDecoration). Текст-форма (только <Title>) →
|
||||
# строка/{text,formatted}. Own-content (layout/оформление/флаги/hyperlink) → объект { text?, … }.
|
||||
# Events компаньона пока НЕ захватываем (хвост — требует имя-обработчик).
|
||||
$etNode = $node.SelectSingleNode("lf:ExtendedTooltip", $ns)
|
||||
if ($etNode) {
|
||||
$etTitle = $etNode.SelectSingleNode("lf:Title", $ns)
|
||||
$textVal = if ($etTitle) { Get-MLFormattedValue $etTitle } else { $null }
|
||||
$etObj = [ordered]@{}
|
||||
Add-Layout $etObj $etNode
|
||||
Add-GenericScalars $etObj $etNode
|
||||
Add-Appearance $etObj $etNode
|
||||
if ((Get-Child $etNode 'Visible') -eq 'false') { $etObj['hidden'] = $true }
|
||||
if ((Get-Child $etNode 'Enabled') -eq 'false') { $etObj['disabled'] = $true }
|
||||
if ((Get-Child $etNode 'Hyperlink') -eq 'true') { $etObj['hyperlink'] = $true }
|
||||
if ($etObj.Count -gt 0) {
|
||||
if ($null -ne $textVal) {
|
||||
if ($textVal -is [System.Collections.IDictionary]) { $etObj['text'] = $textVal['text']; if ($textVal['formatted']) { $etObj['formatted'] = $true } }
|
||||
else { $etObj['text'] = $textVal }
|
||||
}
|
||||
$obj['extendedTooltip'] = $etObj
|
||||
} elseif ($null -ne $textVal) {
|
||||
$obj['extendedTooltip'] = $textVal
|
||||
}
|
||||
}
|
||||
# companion-панели с контентом: AutoCommandBar → commandBar, ContextMenu → contextMenu (любой элемент)
|
||||
$isDynListTable = ($tag -eq 'Table') -and (Has-Child $node 'UpdateOnDataChange')
|
||||
$cb = Decompile-CompanionPanel $node 'AutoCommandBar' $isDynListTable
|
||||
|
||||
Reference in New Issue
Block a user