fix(meta-edit): первый ребёнок в пустом ChildObjects вставал вровень с контейнером

Get-ChildIndent брал отступ из первого пробельного узла контейнера. В контейнере с детьми это
отступ ПЕРЕД первым ребёнком — верно; в пустом (только что раскрытом) единственный пробельный
узел — отступ ЗАКРЫВАЮЩЕГО тега, то есть уровень самого контейнера. Первый добавленный реквизит,
команда или таблица получали отступ <ChildObjects>, а не на табуляцию глубже. То же во вложенном
ChildObjects табличной части.

Платформа такой файл принимает и при выгрузке нормализует, поэтому дефект косметический —
но он задевал любой объект, а сравнивать наш вывод с выгрузкой становилось неудобно.

Эталоны четырёх кейсов пересняты: git diff -w пуст, меняются только отступы. Все 23 снэпшота
meta-edit, доезжающие до платформы, приняты 8.3.24.1691.

Кейс eds-add-table-twice объявил skipPlatformVerify: он нарочно удаляет файл таблицы, оставляя
висячую регистрацию, — платформа отказывает по условию кейса, а не из-за дефекта навыка.

Радиус проверен: та же эвристика есть в cf-edit, form-edit, interface-edit и cfe-borrow (семья
get_child_indent из списка долга check-inline-drift, не сведена). У form-edit пустой контейнер
обрабатывается верно — проверено добавлением элемента в форму с <ChildItems/>; у cf-edit и
cfe-borrow ветка недостижима: в ChildObjects конфигурации всегда есть <Language>.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NBsZA5cr2WFThtgp7i5WVi
This commit is contained in:
Nick Shirokov
2026-09-06 20:15:26 +03:00
co-authored by Claude Opus 5
parent 11c0450d2a
commit 5c79b494cd
7 changed files with 318 additions and 262 deletions
+13 -3
View File
@@ -1,4 +1,4 @@
# meta-edit v1.49 — Edit existing 1C metadata object XML
# meta-edit v1.50 — Edit existing 1C metadata object XML
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
[CmdletBinding(PositionalBinding=$false)]
param(
@@ -749,11 +749,21 @@ function Import-Fragment([string]$xmlString) {
}
function Get-ChildIndent($container) {
# В контейнере с детьми первый пробельный узел — это отступ ПЕРЕД первым ребёнком.
# В пустом (только что раскрытом) единственный пробельный узел — отступ ЗАКРЫВАЮЩЕГО
# тега, то есть уровень самого контейнера: ребёнку нужен на табуляцию глубже. Без этой
# поправки первый ребёнок вставал вровень с <ChildObjects>.
$hasElements = $false
foreach ($child in $container.ChildNodes) {
if ($child.NodeType -eq 'Element') { $hasElements = $true; break }
}
foreach ($child in $container.ChildNodes) {
if ($child.NodeType -eq 'Whitespace' -or $child.NodeType -eq 'SignificantWhitespace') {
$text = $child.Value
if ($text -match '^\r?\n(\t+)$') { return $Matches[1] }
if ($text -match '^\r?\n(\t+)') { return $Matches[1] }
$found = $null
if ($text -match '^\r?\n(\t+)$') { $found = $Matches[1] }
elseif ($text -match '^\r?\n(\t+)') { $found = $Matches[1] }
if ($null -ne $found) { return $(if ($hasElements) { $found } else { "$found`t" }) }
}
}
# Fallback: count depth
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# meta-edit v1.49 — Edit existing 1C metadata object XML
# meta-edit v1.50 — Edit existing 1C metadata object XML
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
@@ -757,17 +757,23 @@ def import_fragment(xml_string):
def get_child_indent(container):
"""Detect indentation of children inside a container element."""
# В контейнере с детьми первый пробельный узел — это отступ ПЕРЕД первым ребёнком.
# В пустом (только что раскрытом) единственный пробельный узел — отступ ЗАКРЫВАЮЩЕГО
# тега, то есть уровень самого контейнера: ребёнку нужен на табуляцию глубже. Без этой
# поправки первый ребёнок вставал вровень с <ChildObjects>.
has_elements = len(container) > 0
extra = "" if has_elements else "\t"
# Check container.text (text before first child)
if container.text and "\n" in container.text:
after_nl = container.text.rsplit("\n", 1)[-1]
if after_nl and not after_nl.strip():
return after_nl
return after_nl + extra
# Check tail of child elements
for child in container:
if child.tail and "\n" in child.tail:
after_nl = child.tail.rsplit("\n", 1)[-1]
if after_nl and not after_nl.strip():
return after_nl
return after_nl + extra
# Fallback: count depth
depth = 0
current = container