diff --git a/.claude/skills/cfe-borrow/scripts/cfe-borrow.ps1 b/.claude/skills/cfe-borrow/scripts/cfe-borrow.ps1 index 0b526b35..89bbe6c6 100644 --- a/.claude/skills/cfe-borrow/scripts/cfe-borrow.ps1 +++ b/.claude/skills/cfe-borrow/scripts/cfe-borrow.ps1 @@ -476,13 +476,23 @@ function Borrow-Form { $formVersion = $srcFormEl.GetAttribute("version") if (-not $formVersion) { $formVersion = "2.17" } - # Find direct children: AutoCommandBar, ChildItems (visual elements only) + # Find direct children: form properties, AutoCommandBar, ChildItems $srcAutoCmd = $null $srcChildItems = $null + $formProps = @() + $reachedVisual = $false foreach ($fc in $srcFormEl.ChildNodes) { if ($fc.NodeType -ne 'Element') { continue } - if ($fc.LocalName -eq 'AutoCommandBar' -and -not $srcAutoCmd) { $srcAutoCmd = $fc } - elseif ($fc.LocalName -eq 'ChildItems' -and -not $srcChildItems) { $srcChildItems = $fc } + if ($fc.LocalName -eq 'AutoCommandBar' -and -not $srcAutoCmd) { + $reachedVisual = $true; $srcAutoCmd = $fc; continue + } + if ($fc.LocalName -eq 'ChildItems' -and -not $srcChildItems) { + $reachedVisual = $true; $srcChildItems = $fc; continue + } + if (-not $reachedVisual) { + # Form-level properties before AutoCommandBar (WindowOpeningMode, AutoFillCheck, etc.) + $formProps += $fc.OuterXml + } } # Get OuterXml and strip redundant namespace redeclarations (they're on root
) @@ -496,6 +506,10 @@ function Borrow-Form { $autoCmdXml = [regex]::Replace($autoCmdXml, '[^<]*', '0') # Replace Autofill true → false $autoCmdXml = $autoCmdXml -replace 'true', 'false' + # Strip DataPath (references base form attributes not present in extension) + $autoCmdXml = [regex]::Replace($autoCmdXml, '\s*[^<]*', '') + # Strip element-level Events (base form event handlers not present in extension) + $autoCmdXml = [regex]::Replace($autoCmdXml, '(?s)\s*.*?', '') } $childItemsXml = "" @@ -504,6 +518,9 @@ function Borrow-Form { $childItemsXml = [regex]::Replace($childItemsXml, $nsStripPattern, '') # Replace all CommandName values with 0 in ChildItems too $childItemsXml = [regex]::Replace($childItemsXml, '[^<]*', '0') + # Strip DataPath and element-level Events + $childItemsXml = [regex]::Replace($childItemsXml, '\s*[^<]*', '') + $childItemsXml = [regex]::Replace($childItemsXml, '(?s)\s*.*?', '') } else { $childItemsXml = "" } @@ -521,7 +538,11 @@ function Borrow-Form { $formXmlSb.Append($formTag) | Out-Null $formXmlSb.Append("`r`n") | Out-Null - # Part 1: visual elements (add leading tab to first line of each block) + # Part 1: form properties + visual elements + foreach ($propXml in $formProps) { + $propXml = [regex]::Replace($propXml, $nsStripPattern, '') + $formXmlSb.Append("`t$propXml`r`n") | Out-Null + } if ($autoCmdXml) { $formXmlSb.Append("`t$autoCmdXml") | Out-Null $formXmlSb.Append("`r`n") | Out-Null @@ -531,10 +552,14 @@ function Borrow-Form { $formXmlSb.Append("`t") | Out-Null $formXmlSb.Append("`r`n") | Out-Null - # BaseForm: same visual elements, indented one more level + # BaseForm: form properties + same visual elements, indented one more level $formXmlSb.Append("`t") | Out-Null $formXmlSb.Append("`r`n") | Out-Null + foreach ($propXml in $formProps) { + $propXml = [regex]::Replace($propXml, $nsStripPattern, '') + $formXmlSb.Append("`t`t$propXml`r`n") | Out-Null + } if ($autoCmdXml) { # Reindent for BaseForm: first line gets 2 tabs, other lines get +1 tab $acLines = $autoCmdXml -split "`r?`n" diff --git a/.claude/skills/cfe-borrow/scripts/cfe-borrow.py b/.claude/skills/cfe-borrow/scripts/cfe-borrow.py index 9b00d514..72c4e39c 100644 --- a/.claude/skills/cfe-borrow/scripts/cfe-borrow.py +++ b/.claude/skills/cfe-borrow/scripts/cfe-borrow.py @@ -653,14 +653,23 @@ def main(): src_auto_cmd = None src_child_items = None + form_props = [] + reached_visual = False for fc in src_form_el: if not isinstance(fc.tag, str): continue ln = localname(fc) if ln == "AutoCommandBar" and src_auto_cmd is None: + reached_visual = True src_auto_cmd = fc - elif ln == "ChildItems" and src_child_items is None: + continue + if ln == "ChildItems" and src_child_items is None: + reached_visual = True src_child_items = fc + continue + if not reached_visual: + # Form-level properties before AutoCommandBar (WindowOpeningMode, AutoFillCheck, etc.) + form_props.append(etree.tostring(fc, encoding="unicode")) ns_strip_pattern = re.compile(r'\s+xmlns(?::\w+)?="[^"]*"') @@ -670,12 +679,19 @@ def main(): auto_cmd_xml = ns_strip_pattern.sub("", auto_cmd_xml) auto_cmd_xml = re.sub(r'[^<]*', '0', auto_cmd_xml) auto_cmd_xml = auto_cmd_xml.replace('true', 'false') + # Strip DataPath (references base form attributes not present in extension) + auto_cmd_xml = re.sub(r'\s*[^<]*', '', auto_cmd_xml) + # Strip element-level Events (base form event handlers not present in extension) + auto_cmd_xml = re.sub(r'\s*.*?', '', auto_cmd_xml, flags=re.DOTALL) child_items_xml = "" if src_child_items is not None: child_items_xml = etree.tostring(src_child_items, encoding="unicode") child_items_xml = ns_strip_pattern.sub("", child_items_xml) child_items_xml = re.sub(r'[^<]*', '0', child_items_xml) + # Strip DataPath and element-level Events + child_items_xml = re.sub(r'\s*[^<]*', '', child_items_xml) + child_items_xml = re.sub(r'\s*.*?', '', child_items_xml, flags=re.DOTALL) else: child_items_xml = "" @@ -696,6 +712,10 @@ def main(): parts.append(form_tag) parts.append("\r\n") + # Form properties (WindowOpeningMode, AutoFillCheck, etc.) + for prop_xml in form_props: + prop_xml_clean = ns_strip_pattern.sub("", prop_xml) + parts.append(f"\t{prop_xml_clean}\r\n") if auto_cmd_xml: parts.append(f"\t{auto_cmd_xml}\r\n") parts.append(f"\t{child_items_xml}\r\n") @@ -704,6 +724,9 @@ def main(): # BaseForm parts.append(f'\t\r\n') + for prop_xml in form_props: + prop_xml_clean = ns_strip_pattern.sub("", prop_xml) + parts.append(f"\t\t{prop_xml_clean}\r\n") if auto_cmd_xml: ac_lines = auto_cmd_xml.split("\n") for li, line in enumerate(ac_lines): diff --git a/docs/1c-extension-spec.md b/docs/1c-extension-spec.md index 465ee2f4..9208cca7 100644 --- a/docs/1c-extension-spec.md +++ b/docs/1c-extension-spec.md @@ -422,6 +422,12 @@ Form.xml заимствованной формы — **двухчастный ф 4. Элемент `` всегда идёт **последним** в `` и имеет атрибут `version`. +5. **Правило ``: удаление** — все элементы `...` из базовых визуальных элементов удаляются (и в Part 1, и в BaseForm). DataPath ссылается на реквизиты формы базовой конфигурации, которые не включены в расширение. Сохраняются только DataPath элементов, добавленных расширением (ссылающихся на собственные реквизиты расширения). + +6. **Правило `` элементов: удаление** — все блоки `` внутри визуальных элементов (AutoCommandBar и ChildItems) удаляются (и в Part 1, и в BaseForm). Обработчики событий базовой конфигурации не переносятся. При модификации формы обработчики расширения добавляются только в Part 1 с атрибутом `callType`. + +7. **Свойства формы** — элементы между `` и `` (например, `WindowOpeningMode`, `AutoFillCheck`, `AutoTitle`, `AutoTime`, `UsePostingMode`, `RepostOnWrite`, `Customizable`, `CommandBarLocation`) копируются из исходной формы в обе части (Part 1 и BaseForm). + #### 5.4.3. Нумерация ID элементов | Диапазон | Принадлежность |