mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-07-30 08:26:55 +03:00
feat(form-decompile,form-compile): унификация событий элементов на events-мапу (кластер Events DSL)
Несогласованность DSL: события ФОРМЫ описывались интуитивной мапой
events:{Событие:Обработчик}, а события ЭЛЕМЕНТА — двумя сущностями
on:[...] + handlers:{...}. Два способа для одного понятия путали модель.
Унифицировано на единую мапу events:{Событие:ИмяОбработчика} на форме И
элементах (как form-level). Декомпилятор эмитит только её, с явными именами
обработчиков (прозрачно, консистентно с form-level).
Компилятор (ps1+py):
- Emit-Events читает events-мапу (основной формат); значение null/"" →
имя по конвенции ИмяЭлемента+суффикс (прощающий fallback).
- legacy on/handlers по-прежнему принимаются ради совместимости (не эмитятся).
- choiceButton: проверка StartChoice через оба формата (Test-ElementEvent).
- events добавлен в whitelist ключей элемента.
Декомпилятор: Get-Events → упорядоченная мапа {Событие:Обработчик} в порядке
документа; убраны on/handlers и инверсия авто-имён.
spec/SKILL.md: events как единственный рекомендованный формат, on/handlers
помечены legacy. В SKILL.md только явные имена (null-сахар — деталь spec,
инструкцию не раздуваем).
Корпус acc_8.3.24: 190 элементов в 114/400 форм теряли Events до фикса (баг
on/handlers разобран отдельным коммитом). Раундтрип 2.17: Events ушли из топа
LOST, match 4→6, 0 compile-fail. Регресс ps+py 32/32, снэпшот events (добавлен
блок Events у поля с переименованным обработчиком) сертифицирован в 1С 8.3.24.
Follow-up: form-edit использует расширенный on с {event,callType} —
унификация отдельным решением (см. BACKLOG).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
a38874280c
commit
4c2c72abce
@@ -1,4 +1,4 @@
|
||||
# form-decompile v0.11 — Decompile 1C managed Form.xml to JSON DSL (draft)
|
||||
# form-decompile v0.12 — Decompile 1C managed Form.xml to JSON DSL (draft)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
# ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью.
|
||||
param(
|
||||
@@ -212,39 +212,19 @@ function Add-TitleLocation {
|
||||
elseif ($tl -ne $smartDefault) { $obj['titleLocation'] = $tl.ToLower() }
|
||||
}
|
||||
|
||||
# Суффиксы авто-имён обработчиков (инверсия компилятора)
|
||||
$HANDLER_SUFFIX = @{
|
||||
'OnChange'='ПриИзменении'; 'StartChoice'='НачалоВыбора'; 'ChoiceProcessing'='ОбработкаВыбора';
|
||||
'AutoComplete'='АвтоПодбор'; 'Clearing'='Очистка'; 'Opening'='Открытие'; 'Click'='Нажатие';
|
||||
'OnActivateRow'='ПриАктивизацииСтроки'; 'BeforeAddRow'='ПередНачаломДобавления';
|
||||
'BeforeDeleteRow'='ПередУдалением'; 'BeforeRowChange'='ПередНачаломИзменения';
|
||||
'OnStartEdit'='ПриНачалеРедактирования'; 'OnEndEdit'='ПриОкончанииРедактирования';
|
||||
'Selection'='ВыборСтроки'; 'OnCurrentPageChange'='ПриСменеСтраницы'; 'TextEditEnd'='ОкончаниеВводаТекста';
|
||||
'URLProcessing'='ОбработкаНавигационнойСсылки'; 'DragStart'='НачалоПеретаскивания'; 'Drag'='Перетаскивание';
|
||||
'DragCheck'='ПроверкаПеретаскивания'; 'Drop'='Помещение'; 'AfterDeleteRow'='ПослеУдаления'
|
||||
}
|
||||
|
||||
# Разобрать <Events> элемента → { on:[...], handlers:{...} } с учётом авто-имён
|
||||
# Разобрать <Events> элемента → упорядоченная мапа { ИмяСобытия: ИмяОбработчика }
|
||||
# в порядке документа. Имена обработчиков всегда явные (как у событий формы) —
|
||||
# единый, консистентный с form-level формат. Legacy on/handlers больше не эмитим.
|
||||
function Get-Events {
|
||||
param($node, [string]$elName)
|
||||
$ev = $node.SelectSingleNode("lf:Events", $ns)
|
||||
if (-not $ev) { return $null }
|
||||
$on = New-Object System.Collections.ArrayList
|
||||
$handlers = [ordered]@{}
|
||||
# `on` — полный список событий в порядке документа (контракт DSL: on = массив имён событий);
|
||||
# `handlers` — только переопределение имени, когда обработчик не выводится из авто-суффикса.
|
||||
$events = [ordered]@{}
|
||||
foreach ($e in @($ev.SelectNodes("lf:Event", $ns))) {
|
||||
$evName = $e.GetAttribute("name")
|
||||
$handler = $e.InnerText
|
||||
$auto = if ($HANDLER_SUFFIX.ContainsKey($evName) -and $elName) { "$elName$($HANDLER_SUFFIX[$evName])" } else { $null }
|
||||
[void]$on.Add($evName)
|
||||
if (-not ($auto -and $handler -eq $auto)) { $handlers[$evName] = $handler }
|
||||
$events[$e.GetAttribute("name")] = $e.InnerText
|
||||
}
|
||||
$res = [ordered]@{}
|
||||
if ($on.Count -gt 0) { $res['on'] = @($on) }
|
||||
if ($handlers.Count -gt 0) { $res['handlers'] = $handlers }
|
||||
if ($res.Count -eq 0) { return $null }
|
||||
return $res
|
||||
if ($events.Count -eq 0) { return $null }
|
||||
return $events
|
||||
}
|
||||
|
||||
# Общие свойства элемента (visible/enabled/readonly/title/events) → в hash
|
||||
@@ -260,10 +240,7 @@ function Add-CommonProps {
|
||||
# formatted у LabelDecoration выводится компилятором из hyperlink — отдельный ключ не нужен (#16 хвост)
|
||||
}
|
||||
$ev = Get-Events $node $elName
|
||||
if ($ev) {
|
||||
if ($ev.Contains('on')) { $obj['on'] = $ev['on'] }
|
||||
if ($ev.Contains('handlers')) { $obj['handlers'] = $ev['handlers'] }
|
||||
}
|
||||
if ($ev) { $obj['events'] = $ev }
|
||||
}
|
||||
|
||||
# --- 3. Type decompile (inverse of Emit-Type) ---
|
||||
|
||||
Reference in New Issue
Block a user