feat: Divi save pipeline – tree_rev lock, kses-safe save, revision, flags, cache, ToolResult
DiviSaver/DiviWriter/DiviComposition/DiviChange, WpValueSanitizer (S4), WpMediaResolver, DiviFlags (S11), DynamicContentMap from Divi's live registry (S22), S31 wiring, S35 control strip at apply() entry. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -193,7 +193,6 @@ final class ShortformWriterTest extends TestCase
|
||||
'url: line-break octet marker' => ['url', '$variable%0a(y)$'],
|
||||
'url: nested line-break octet marker' => ['url', '$variable%0%0aa(y)$'],
|
||||
'color: tag-split marker' => ['color', '$variable<x>(' . substr($color, 10)],
|
||||
'color: NUL-split marker' => ['color', '$variable' . chr(0) . '(' . substr($color, 10)],
|
||||
'color: octet-split marker' => ['color', '$variable%41(' . substr($color, 10)],
|
||||
];
|
||||
}
|
||||
@@ -318,4 +317,38 @@ final class ShortformWriterTest extends TestCase
|
||||
self::assertSame([], $admin['errors']);
|
||||
self::assertSame('Hallo', $admin['attrs']['module']['advanced']['html']['desktop']['value']['htmlBefore']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruling S35: controls go once at the entry of apply(), before placeholder resolution and
|
||||
* trim – "{\0{post:title}}" is the placeholder, checked like any other.
|
||||
*/
|
||||
public function testControlCharactersGoBeforePlaceholderResolution(): void
|
||||
{
|
||||
$writer = ComposeFixture::shortform();
|
||||
|
||||
foreach ([chr(0), chr(1), chr(11), chr(127)] as $control) {
|
||||
$result = $writer->apply('heading', [], ['text' => '{' . $control . '{post:title}}'], 'n');
|
||||
self::assertSame([], $result['errors'], (string) ord($control));
|
||||
self::assertSame(
|
||||
'$variable({"type":"content","value":{"name":"post_title","settings":{"before":"","after":""}}})$',
|
||||
$result['attrs']['title']['innerContent']['desktop']['value']
|
||||
);
|
||||
|
||||
$embedded = $writer->apply('heading', [], ['text' => 'Hallo {' . $control . '{post:title}}'], 'n');
|
||||
self::assertStringContainsString('allein im Wert', $embedded['errors']['n.text']);
|
||||
self::assertSame([], $embedded['attrs']);
|
||||
|
||||
// A control-split whole reference IS the reference (S32a/S35): validated and re-serialized.
|
||||
$reference = '$variable({"type":"color","value":{"name":"gcid-a1b2","settings":{}}})$';
|
||||
$split = $writer->apply('divider', [], ['color' => '$variable' . $control . substr($reference, 9)], 'n');
|
||||
self::assertSame([], $split['errors']);
|
||||
self::assertSame($reference, $split['attrs']['divider']['advanced']['line']['desktop']['value']['color']);
|
||||
|
||||
// Colors: the placeholder resolves after the strip (and trim), then the color check.
|
||||
$color = $writer->apply('divider', [], ['color' => ' {{color:Nacht' . $control . 'blau}} '], 'n');
|
||||
self::assertSame([], $color['errors']);
|
||||
self::assertStringContainsString('gcid-a1b2', $color['attrs']['divider']['advanced']['line']['desktop']['value']['color']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user