diff --git a/.claude/skills/form-compile/scripts/form-compile.ps1 b/.claude/skills/form-compile/scripts/form-compile.ps1
index edc55841..624681d1 100644
--- a/.claude/skills/form-compile/scripts/form-compile.ps1
+++ b/.claude/skills/form-compile/scripts/form-compile.ps1
@@ -1,4 +1,4 @@
-# form-compile v1.119 — Compile 1C managed form from JSON or object metadata
+# form-compile v1.120 — Compile 1C managed form from JSON or object metadata
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[string]$JsonPath,
@@ -3555,6 +3555,9 @@ function Emit-ColumnGroup {
Emit-CommonFlags -el $el -indent $inner
Emit-Layout -el $el -indent $inner
+ # Картинка заголовка колонки-группы (после ShowInHeader/Layout, перед оформлением — порядок XSD)
+ Emit-ColumnPics -el $el -indent $inner
+
# Оформление (цвета/шрифты/граница) — перед компаньоном
Emit-Appearance -el $el -indent $inner -profile 'field'
@@ -4387,6 +4390,9 @@ function Emit-Page {
if ($el.showTitle -eq $false) { X "$innerfalse" }
Emit-Layout -el $el -indent $inner
+ # Оформление страницы (BackColor / TitleTextColor / TitleFont) — после ShowTitle, перед компаньоном
+ Emit-Appearance -el $el -indent $inner -profile 'field'
+
# Companion
Emit-Companion -tag "ExtendedTooltip" -name "${name}РасширеннаяПодсказка" -indent $inner -content $el.extendedTooltip
@@ -4753,6 +4759,10 @@ function Emit-Popup {
X "$inner$($el.representation)"
}
Emit-Layout -el $el -indent $inner
+
+ # Оформление попапа (TitleTextColor / TitleFont) — перед компаньоном
+ Emit-Appearance -el $el -indent $inner -profile 'field'
+
Emit-Companion -tag "ExtendedTooltip" -name "${name}РасширеннаяПодсказка" -indent $inner -content $el.extendedTooltip
# Children
diff --git a/.claude/skills/form-compile/scripts/form-compile.py b/.claude/skills/form-compile/scripts/form-compile.py
index 2c2b7808..688e8016 100644
--- a/.claude/skills/form-compile/scripts/form-compile.py
+++ b/.claude/skills/form-compile/scripts/form-compile.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# form-compile v1.119 — Compile 1C managed form from JSON or object metadata
+# form-compile v1.120 — Compile 1C managed form from JSON or object metadata
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
import copy
@@ -3642,6 +3642,9 @@ def emit_column_group(lines, el, name, eid, indent):
emit_common_flags(lines, el, inner)
emit_layout(lines, el, inner)
+ # Картинка заголовка колонки-группы (после ShowInHeader/Layout, перед оформлением — порядок XSD)
+ emit_column_pics(lines, el, inner)
+
# Оформление (цвета/шрифты/граница) — перед компаньоном
emit_appearance(lines, el, inner, 'field')
@@ -4112,6 +4115,9 @@ def emit_page(lines, el, name, eid, indent):
lines.append(f'{inner}false')
emit_layout(lines, el, inner)
+ # \u041e\u0444\u043e\u0440\u043c\u043b\u0435\u043d\u0438\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b (BackColor / TitleTextColor / TitleFont) \u2014 \u043f\u043e\u0441\u043b\u0435 ShowTitle, \u043f\u0435\u0440\u0435\u0434 \u043a\u043e\u043c\u043f\u0430\u043d\u044c\u043e\u043d\u043e\u043c
+ emit_appearance(lines, el, inner, 'field')
+
# Companion
emit_companion(lines, 'ExtendedTooltip', f'{name}\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u0430\u044f\u041f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0430', inner, el.get('extendedTooltip'))
@@ -4433,6 +4439,10 @@ def emit_popup(lines, el, name, eid, indent):
if el.get('representation'):
lines.append(f'{inner}{el["representation"]}')
emit_layout(lines, el, inner)
+
+ # Оформление попапа (TitleTextColor / TitleFont) — перед компаньоном
+ emit_appearance(lines, el, inner, 'field')
+
emit_companion(lines, 'ExtendedTooltip', f'{name}РасширеннаяПодсказка', inner, el.get('extendedTooltip'))
# Children
diff --git a/.claude/skills/form-decompile/scripts/form-decompile.ps1 b/.claude/skills/form-decompile/scripts/form-decompile.ps1
index a986cf00..22df1abb 100644
--- a/.claude/skills/form-decompile/scripts/form-decompile.ps1
+++ b/.claude/skills/form-decompile/scripts/form-decompile.ps1
@@ -1,4 +1,4 @@
-# form-decompile v0.95 — Decompile 1C managed Form.xml to JSON DSL (draft)
+# form-decompile v0.96 — Decompile 1C managed Form.xml to JSON DSL (draft)
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
# ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью.
param(
@@ -274,6 +274,16 @@ function Get-LangText {
return $map
}
+# Get-LangText с восстановлением значимого пробела: PreserveWhitespace=false стрипает
+# → "" (неотличимо от суппресса). Платформа НЕ эмитит пустой
+# Title/ToolTip, значит исходно был пробел → возвращаем " " (как Get-MLFormattedValue).
+function Get-LangTextWS {
+ param($node)
+ $t = Get-LangText $node
+ if ($t -is [string] -and $t -eq '' -and $node.SelectSingleNode("v8:item/v8:content", $ns)) { return ' ' }
+ return $t
+}
+
# Авто-вывод заголовка из имени — ТОЧНОЕ зеркало Title-FromName из form-compile.
# Нужен, чтобы опускать ru-only заголовки, которые компилятор воспроизведёт сам.
function Title-FromName {
@@ -1074,12 +1084,12 @@ function Add-CommonProps {
$uv = Decompile-XrFlag $node 'UserVisible'; if ($null -ne $uv) { $obj['userVisible'] = $uv }
$titleNode = $node.SelectSingleNode("lf:Title", $ns)
if ($titleNode) {
- $t = Get-LangText $titleNode
+ $t = Get-LangTextWS $titleNode # восстановление значимого пробела (whitespace-заголовок)
if ($null -ne $t) { $obj['title'] = $t }
# formatted у LabelDecoration выводится компилятором из hyperlink — отдельный ключ не нужен (#16 хвост)
}
$ttNode = $node.SelectSingleNode("lf:ToolTip", $ns)
- if ($ttNode) { $tt = Get-LangText $ttNode; if ($null -ne $tt) { $obj['tooltip'] = $tt } }
+ if ($ttNode) { $tt = Get-LangTextWS $ttNode; if ($null -ne $tt) { $obj['tooltip'] = $tt } }
$ttr = Get-Child $node 'ToolTipRepresentation'; if ($ttr) { $obj['tooltipRepresentation'] = $ttr }
# Картинки заголовка/подвала колонки (любой field-тип, эмитятся платформой как column header/footer icon)
$hp = Get-PictureRef $node 'HeaderPicture'; if ($null -ne $hp) { $obj['headerPicture'] = $hp }
diff --git a/docs/form-dsl-spec.md b/docs/form-dsl-spec.md
index 68cb0a74..4e30ef4f 100644
--- a/docs/form-dsl-spec.md
+++ b/docs/form-dsl-spec.md
@@ -212,7 +212,7 @@ companion-панели с собственным контентом. Оба не
### 4.1e. Оформление элемента (цвета / шрифты / граница)
-Прямые свойства оформления элемента. Ключи — англ. camelCase 1:1 с тегами; **принимаются рус. синонимы** (forgiving). Применимо к полям (input/check/radio/labelField/picField/calendar), декорациям (label/picture), кнопкам (button), группам (group/columnGroup) и таблицам (table); порядок тегов в XML — по базовому типу (профиль), компилятор расставляет сам (1С толерантна к порядку оформления внутри элемента).
+Прямые свойства оформления элемента. Ключи — англ. camelCase 1:1 с тегами; **принимаются рус. синонимы** (forgiving). Применимо к полям (input/check/radio/labelField/picField/calendar), декорациям (label/picture), кнопкам (button), группам (group/columnGroup), **страницам (page: `backColor`/`titleTextColor`/`titleFont`)**, **попапам (popup: `titleTextColor`/`titleFont`)** и таблицам (table); порядок тегов в XML — по базовому типу (профиль), компилятор расставляет сам (1С толерантна к порядку оформления внутри элемента).
| Ключ | Тег | Рус. синоним |
|------|-----|--------------|
@@ -282,7 +282,7 @@ companion-панели с собственным контентом. Оба не
| `viewMode` / `verticalScrollBar` / `rowInputMode` | ``/… | свойства таблицы (pass-through) |
> Эти простые скаляры — pass-through (captured/emitted «как есть»), применимы там, где платформа их пишет.
-> `defaultItem`/`enableStartDrag`/`fileDragMode`/`skipOnInput` + cell-свойства (`showInHeader`/`showInFooter`/`autoCellHeight`/`footerHorizontalAlign`/`headerHorizontalAlign`/`headerPicture`/`footerPicture`) — общие для любого поля-колонки (input, label, picField, check).
+> `defaultItem`/`enableStartDrag`/`fileDragMode`/`skipOnInput` + cell-свойства (`showInHeader`/`showInFooter`/`autoCellHeight`/`footerHorizontalAlign`/`headerHorizontalAlign`/`headerPicture`/`footerPicture`) — общие для любого поля-колонки (input, label, picField, check) и `columnGroup` (картинка заголовка группы колонок).
#### Картинка-ссылка (`headerPicture`/`footerPicture`/`valuesPicture`/`rowsPicture`/Page `picture`)
diff --git a/tests/skills/cases/form-compile/button-group.json b/tests/skills/cases/form-compile/button-group.json
index e3b607a2..3b58e4ea 100644
--- a/tests/skills/cases/form-compile/button-group.json
+++ b/tests/skills/cases/form-compile/button-group.json
@@ -23,7 +23,7 @@
{ "button": "Вниз", "command": "Вниз" }
]},
{ "buttonGroup": "ГруппаГлобальныеКоманды", "commandSource": "FormCommandPanelGlobalCommands" },
- { "popup": "ПодменюПечать", "title": "Печать", "picture": "StdPicture.Print", "loadTransparent": false, "representation": "PictureAndText", "children": [
+ { "popup": "ПодменюПечать", "title": "Печать", "picture": "StdPicture.Print", "loadTransparent": false, "representation": "PictureAndText", "titleTextColor": "style:ButtonTextColor", "titleFont": "style:ВажнаяНадписьШрифт", "children": [
{ "button": "ПечатьСчёта", "command": "Выполнить" }
]}
]}
diff --git a/tests/skills/cases/form-compile/column-group.json b/tests/skills/cases/form-compile/column-group.json
index 6243fc13..c3850cee 100644
--- a/tests/skills/cases/form-compile/column-group.json
+++ b/tests/skills/cases/form-compile/column-group.json
@@ -18,7 +18,7 @@
"elements": [
{ "table": "Список", "path": "Список", "columns": [
{ "input": "Наименование", "path": "Список.Наименование" },
- { "columnGroup": "horizontal", "name": "ГруппаСрок", "title": "Срок", "children": [
+ { "columnGroup": "horizontal", "name": "ГруппаСрок", "title": "Срок", "headerPicture": "StdPicture.ExecuteTask", "children": [
{ "input": "ДатаНачала", "path": "Список.ДатаНачала" },
{ "input": "ДатаОкончания", "path": "Список.ДатаОкончания" }
]},
diff --git a/tests/skills/cases/form-compile/pages.json b/tests/skills/cases/form-compile/pages.json
index 9b413c4e..8c453a44 100644
--- a/tests/skills/cases/form-compile/pages.json
+++ b/tests/skills/cases/form-compile/pages.json
@@ -21,7 +21,7 @@
{ "page": "Шаг1", "title": "", "showTitle": false, "picture": "StdPicture.ExecuteTask", "children": [
{ "input": "Параметр1", "path": "Параметр1" }
]},
- { "page": "Шаг2", "title": "Результат", "titleDataPath": "Итог", "tooltip": "Шаг \"Результат\"", "group": "horizontalIfPossible", "picture": { "src": "StdPicture.FilterCriterion", "loadTransparent": true, "transparentPixel": { "x": 2, "y": 4 } }, "children": [
+ { "page": "Шаг2", "title": "Результат", "titleDataPath": "Итог", "tooltip": "Шаг \"Результат\"", "group": "horizontalIfPossible", "picture": { "src": "StdPicture.FilterCriterion", "loadTransparent": true, "transparentPixel": { "x": 2, "y": 4 } }, "backColor": "style:FormBackColor", "titleTextColor": "style:FormTextColor", "titleFont": "style:TextFont", "children": [
{ "input": "Итог", "path": "Итог", "readOnly": true }
]}
]},
diff --git a/tests/skills/cases/form-compile/snapshots/button-group/DataProcessors/ГруппыКнопок/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/button-group/DataProcessors/ГруппыКнопок/Forms/Форма/Ext/Form.xml
index 2dd3c050..a114d5d3 100644
--- a/tests/skills/cases/form-compile/snapshots/button-group/DataProcessors/ГруппыКнопок/Forms/Форма/Ext/Form.xml
+++ b/tests/skills/cases/form-compile/snapshots/button-group/DataProcessors/ГруппыКнопок/Forms/Форма/Ext/Form.xml
@@ -57,6 +57,8 @@
false
PictureAndText
+ style:ButtonTextColor
+