refactor: small Divi tree helpers out of DiviWriter (M3)
Block::isPlaceholder replaces the divi/placeholder literals (ledger T4); NodeIndex::parentBlock/sectionLabel replace the two parentBlock copies and DiviWriter::sectionLabel; DiviChange::idOf and Outline::summary replace the duplicated id resolution and outline text; DiviSchema holds the shared input properties. Behaviour unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
This commit is contained in:
@@ -121,6 +121,12 @@ final class Block extends Container
|
||||
return str_starts_with($this->name, 'divi/');
|
||||
}
|
||||
|
||||
/** The divi/placeholder wrapper the builder puts around a page's sections (transparent for IDs). */
|
||||
public function isPlaceholder(): bool
|
||||
{
|
||||
return $this->name === 'divi/placeholder';
|
||||
}
|
||||
|
||||
/** A global module reference or global layout (edited only in Etappe 3). */
|
||||
public function isGlobal(): bool
|
||||
{
|
||||
|
||||
@@ -36,7 +36,7 @@ final class NodeIndex
|
||||
{
|
||||
$root = $document;
|
||||
foreach ($document->children() as $block) {
|
||||
if ($block->name() === 'divi/placeholder') {
|
||||
if ($block->isPlaceholder()) {
|
||||
$root = $block;
|
||||
break;
|
||||
}
|
||||
@@ -92,6 +92,26 @@ final class NodeIndex
|
||||
return $parent instanceof Block ? $this->idOf($parent) : null;
|
||||
}
|
||||
|
||||
/** The parent node of $block; null at the top level (the root or a placeholder holds it). */
|
||||
public function parentBlock(Block $block): ?Block
|
||||
{
|
||||
$parent = $this->parentOf($block);
|
||||
|
||||
return $parent instanceof Block && ! $parent->isPlaceholder() ? $parent : null;
|
||||
}
|
||||
|
||||
/** Admin label of the section around $block (or $block itself), for automatic labels ("" when none). */
|
||||
public function sectionLabel(?Block $block): string
|
||||
{
|
||||
for ($node = $block; $node !== null; $node = $this->parentBlock($node)) {
|
||||
if ($node->name() === 'divi/section') {
|
||||
return NodeSummary::label($node);
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/** @return list<array{id: string, block: Block, depth: int}> In document order. */
|
||||
public function entries(): array
|
||||
{
|
||||
@@ -102,7 +122,7 @@ final class NodeIndex
|
||||
private function walk(Container $container, string $prefix, int $depth, array &$counters): void
|
||||
{
|
||||
foreach ($container->children() as $block) {
|
||||
if ($prefix === '' && $block->name() === 'divi/placeholder') {
|
||||
if ($prefix === '' && $block->isPlaceholder()) {
|
||||
$this->walk($block, '', $depth, $counters);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,29 @@ final class Outline
|
||||
return $this->truncated;
|
||||
}
|
||||
|
||||
/**
|
||||
* The outline text of a write result: the whole page ($sectionIds null) or the given
|
||||
* sections one after another (none: text null), and whether any breadth cap fired (S18).
|
||||
*
|
||||
* @param list<string>|null $sectionIds
|
||||
* @return array{text: ?string, truncated: bool}
|
||||
*/
|
||||
public function summary(NodeIndex $index, ?array $sectionIds = null): array
|
||||
{
|
||||
if ($sectionIds === []) {
|
||||
return ['text' => null, 'truncated' => false];
|
||||
}
|
||||
|
||||
$texts = [];
|
||||
$truncated = false;
|
||||
foreach ($sectionIds ?? [null] as $sectionId) {
|
||||
$texts[] = $this->text($this->rows($index, $sectionId));
|
||||
$truncated = $truncated || $this->wasTruncated();
|
||||
}
|
||||
|
||||
return ['text' => implode("\n", $texts), 'truncated' => $truncated];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<array{id: string, type: string, label: string, excerpt: string, info: string,
|
||||
* presets: list<string>, children: int, editable: bool, depth: int, truncated: bool}>
|
||||
|
||||
Reference in New Issue
Block a user