From b0c2a59f37d8490fdfad3ea251204b6ead50d6b2 Mon Sep 17 00:00:00 2001 From: matlec Date: Thu, 9 Jan 2025 12:51:25 +0100 Subject: [PATCH] [VarDumper] Fix blank strings display --- .../Component/VarDumper/Dumper/HtmlDumper.php | 81 ++++++++++--------- .../Tests/Caster/ExceptionCasterTest.php | 8 +- .../VarDumper/Tests/Caster/StubCasterTest.php | 4 +- .../VarDumper/Tests/Dumper/HtmlDumperTest.php | 20 ++--- 4 files changed, 59 insertions(+), 54 deletions(-) diff --git a/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php b/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php index ea09e68194cb1..cb41112792dfa 100644 --- a/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php +++ b/src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php @@ -663,7 +663,7 @@ function showCurrent(state) height: 0; clear: both; } -pre.sf-dump span { +pre.sf-dump .sf-dump-ellipsization { display: inline-flex; } pre.sf-dump a { @@ -681,16 +681,12 @@ function showCurrent(state) background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAAHUlEQVQY02O8zAABilCaiQEN0EeA8QuUcX9g3QEAAjcC5piyhyEAAAAASUVORK5CYII=) #D3D3D3; } pre.sf-dump .sf-dump-ellipsis { - display: inline-block; - overflow: visible; text-overflow: ellipsis; - max-width: 5em; white-space: nowrap; overflow: hidden; - vertical-align: top; } -pre.sf-dump .sf-dump-ellipsis+.sf-dump-ellipsis { - max-width: none; +pre.sf-dump .sf-dump-ellipsis-tail { + flex-shrink: 0; } pre.sf-dump code { display:inline; @@ -863,66 +859,75 @@ protected function style(string $style, string $value, array $attr = []): string return sprintf('%s', $this->dumpId, $r, 1 + $attr['count'], $v); } + $dumpClasses = ['sf-dump-'.$style]; + $dumpTitle = ''; + if ('const' === $style && isset($attr['value'])) { - $style .= sprintf(' title="%s"', esc(\is_scalar($attr['value']) ? $attr['value'] : json_encode($attr['value']))); + $dumpTitle = esc(\is_scalar($attr['value']) ? $attr['value'] : json_encode($attr['value'])); } elseif ('public' === $style) { - $style .= sprintf(' title="%s"', empty($attr['dynamic']) ? 'Public property' : 'Runtime added dynamic property'); + $dumpTitle = empty($attr['dynamic']) ? 'Public property' : 'Runtime added dynamic property'; } elseif ('str' === $style && 1 < $attr['length']) { - $style .= sprintf(' title="%d%s characters"', $attr['length'], $attr['binary'] ? ' binary or non-UTF-8' : ''); + $dumpTitle = sprintf('%d%s characters', $attr['length'], $attr['binary'] ? ' binary or non-UTF-8' : ''); } elseif ('note' === $style && 0 < ($attr['depth'] ?? 0) && false !== $c = strrpos($value, '\\')) { - $style .= ' title=""'; $attr += [ 'ellipsis' => \strlen($value) - $c, 'ellipsis-type' => 'note', 'ellipsis-tail' => 1, ]; } elseif ('protected' === $style) { - $style .= ' title="Protected property"'; + $dumpTitle = 'Protected property'; } elseif ('meta' === $style && isset($attr['title'])) { - $style .= sprintf(' title="%s"', esc($this->utf8Encode($attr['title']))); + $dumpTitle = esc($this->utf8Encode($attr['title'])); } elseif ('private' === $style) { - $style .= sprintf(' title="Private property defined in class: `%s`"', esc($this->utf8Encode($attr['class']))); + $dumpTitle = sprintf('Private property defined in class: `%s`"', esc($this->utf8Encode($attr['class']))); } if (isset($attr['ellipsis'])) { - $class = 'sf-dump-ellipsis'; + $dumpClasses[] = 'sf-dump-ellipsization'; + $ellipsisClass = 'sf-dump-ellipsis'; if (isset($attr['ellipsis-type'])) { - $class = sprintf('"%s sf-dump-ellipsis-%s"', $class, $attr['ellipsis-type']); + $ellipsisClass .= ' sf-dump-ellipsis-'.$attr['ellipsis-type']; } $label = esc(substr($value, -$attr['ellipsis'])); - $style = str_replace(' title="', " title=\"$v\n", $style); - $v = sprintf('%s', $class, substr($v, 0, -\strlen($label))); + $dumpTitle = $v."\n".$dumpTitle; + $v = sprintf('%s', $ellipsisClass, substr($v, 0, -\strlen($label))); if (!empty($attr['ellipsis-tail'])) { $tail = \strlen(esc(substr($value, -$attr['ellipsis'], $attr['ellipsis-tail']))); - $v .= sprintf('%s%s', $class, substr($label, 0, $tail), substr($label, $tail)); + $v .= sprintf('%s%s', $ellipsisClass, substr($label, 0, $tail), substr($label, $tail)); } else { - $v .= $label; + $v .= sprintf('%s', $label); } } $map = static::$controlCharsMap; - $v = "".preg_replace_callback(static::$controlCharsRx, function ($c) use ($map) { - $s = $b = '%s', + 1 === count($dumpClasses) ? '' : '"', + implode(' ', $dumpClasses), + $dumpTitle ? ' title="'.$dumpTitle.'"' : '', + preg_replace_callback(static::$controlCharsRx, function ($c) use ($map) { + $s = $b = ''; - }, $v).''; + return $s.''; + }, $v) + ); if (!($attr['binary'] ?? false)) { $v = preg_replace_callback(static::$unicodeCharsRx, function ($c) { diff --git a/src/Symfony/Component/VarDumper/Tests/Caster/ExceptionCasterTest.php b/src/Symfony/Component/VarDumper/Tests/Caster/ExceptionCasterTest.php index f8fe43d8ddcee..dcdc36715c1ab 100644 --- a/src/Symfony/Component/VarDumper/Tests/Caster/ExceptionCasterTest.php +++ b/src/Symfony/Component/VarDumper/Tests/Caster/ExceptionCasterTest.php @@ -259,12 +259,12 @@ public function testHtmlDump() Exception { #message: "1" #code: 0 - #file: "%s%eVarDumper%eTests%eCaster%eExceptionCasterTest.php" + #file: "%s%eVarDumper%eTests%eCaster%eExceptionCasterTest.php" #line: %d trace: { - %s%eVarDumper%eTests%eCaster%eExceptionCasterTest.php:%d + %s%eVarDumper%eTests%eCaster%eExceptionCasterTest.php:%d …%d } } diff --git a/src/Symfony/Component/VarDumper/Tests/Caster/StubCasterTest.php b/src/Symfony/Component/VarDumper/Tests/Caster/StubCasterTest.php index cf0bc7338326d..eb110b481aec8 100644 --- a/src/Symfony/Component/VarDumper/Tests/Caster/StubCasterTest.php +++ b/src/Symfony/Component/VarDumper/Tests/Caster/StubCasterTest.php @@ -175,8 +175,8 @@ public function testClassStubWithNotExistingClass() $expectedDump = <<<'EODUMP' array:1 [ - 0 => "Symfony\Component\VarDumper\Tests\Caster\NotExisting" + 0 => "Symfony\Component\VarDumper\Tests\Caster\NotExisting" ] EODUMP; diff --git a/src/Symfony/Component/VarDumper/Tests/Dumper/HtmlDumperTest.php b/src/Symfony/Component/VarDumper/Tests/Dumper/HtmlDumperTest.php index 9b914ad6d3c37..d843e14371f69 100644 --- a/src/Symfony/Component/VarDumper/Tests/Dumper/HtmlDumperTest.php +++ b/src/Symfony/Component/VarDumper/Tests/Dumper/HtmlDumperTest.php @@ -79,18 +79,18 @@ public function testGet() seekable: true %A options: [] } - "obj" => Symfony\Component\VarDumper\Tests\Fixture\DumbFoo {#%d + "obj" => Symfony\Component\VarDumper\Tests\Fixture\DumbFoo {#%d +foo: "foo" +"bar": "bar" } "closure" => Closure(\$a, ?PDO &\$b = null) {#%d - class: "Symfony\Component\VarDumper\Tests\Dumper\HtmlDumperTest" - this: Symfony\Component\VarDumper\Tests\Dumper\HtmlDumperTest {#%d &%s;} - file: "%s%eVarDumper%eTests%eFixtures%edumb-var.php" + class: "Symfony\Component\VarDumper\Tests\Dumper\HtmlDumperTest" + this: Symfony\Component\VarDumper\Tests\Dumper\HtmlDumperTest {#%d &%s;} + file: "%s%eVarDumper%eTests%eFixtures%edumb-var.php" line: "{$var['line']} to {$var['line']}" } "line" => {$var['line']} @@ -101,8 +101,8 @@ public function testGet() 0 => &4 array:1 [&4] ] 8 => &1 null - "sobj" => Symfony\Component\VarDumper\Tests\Fixture\DumbFoo {#%d} + "sobj" => Symfony\Component\VarDumper\Tests\Fixture\DumbFoo {#%d} "snobj" => &3 {#%d} "snobj2" => {#%d} "file" => "{$var['file']}"