Permalink
Browse files

Dumper: lazy loading for collapsed content

It will greatly speed up large dumps rendering.
  • Loading branch information...
dg committed Feb 12, 2019
1 parent 2d66aaf commit 9527a623e44156f0f701e7bcde4212e9a813b3bf
Showing with 50 additions and 31 deletions.
  1. +19 −5 src/Tracy/Dumper.php
  2. +5 −0 src/Tracy/assets/Toggle/toggle.js
  3. +26 −26 tests/Tracy/Dumper.toHtml().phpt
@@ -34,6 +34,9 @@ class Dumper
public const
HIDDEN_VALUE = '*****';
private const
LAZY_LOADING = 'html';
/** @var array */
public static $terminalColors = [
'bool' => '1;33',
@@ -100,6 +103,7 @@ public static function toHtml($var, array $options = []): string
self::OBJECT_EXPORTERS => null,
self::DEBUGINFO => false,
self::KEYS_TO_HIDE => [],
self::LAZY_LOADING => true,
];
$loc = &$options[self::LOCATION];
$loc = $loc === true ? ~0 : (int) $loc;
@@ -130,7 +134,7 @@ public static function toHtml($var, array $options = []): string
*/
public static function toText($var, array $options = []): string
{
$s = self::toHtml($var, $options);
$s = self::toHtml($var, [self::LAZY_LOADING => false] + $options);
return htmlspecialchars_decode(strip_tags($s), ENT_QUOTES);
}
@@ -140,7 +144,7 @@ public static function toText($var, array $options = []): string
*/
public static function toTerminal($var, array $options = []): string
{
$s = self::toHtml($var, $options);
$s = self::toHtml($var, [self::LAZY_LOADING => false] + $options);
$s = preg_replace_callback('#<span class="tracy-dump-(\w+)">|</span>#', function ($m): string {
return "\033[" . (isset($m[1], self::$terminalColors[$m[1]]) ? self::$terminalColors[$m[1]] : '0') . 'm';
}, $s);
@@ -217,6 +221,8 @@ private static function dumpArray(&$var, array $options, int $level): string
$collapsed = $level
? count($var) >= $options[self::COLLAPSE_COUNT]
: (is_int($options[self::COLLAPSE]) ? count($var) >= $options[self::COLLAPSE] : $options[self::COLLAPSE]);
$lazy = $collapsed && $options[self::LAZY_LOADING];
$options[self::LAZY_LOADING] = $lazy ? false : $options[self::LAZY_LOADING];
$inner = '';
$var[$marker] = true;
@@ -232,7 +238,10 @@ private static function dumpArray(&$var, array $options, int $level): string
unset($var[$marker]);
return '<span class="tracy-toggle' . ($collapsed ? ' tracy-collapsed' : '') . '">' . $out . count($var) . ")</span>\n"
. '<div' . ($collapsed ? ' class="tracy-collapsed"' : '') . '>' . $inner . '</div>';
. '<div'
. ($collapsed ? ' class="tracy-collapsed"' : '')
. ($lazy ? ' data-tracy-content="' . Helpers::escapeHtml($inner) . '"' : '')
. '>' . ($lazy ? '' : $inner) . '</div>';
} else {
return $out . count($var) . ") [ ... ]\n";
@@ -273,6 +282,8 @@ private static function dumpObject(&$var, array $options, int $level): string
$collapsed = $level
? count($fields) >= $options[self::COLLAPSE_COUNT]
: (is_int($options[self::COLLAPSE]) ? count($fields) >= $options[self::COLLAPSE] : $options[self::COLLAPSE]);
$lazy = $collapsed && $options[self::LAZY_LOADING];
$options[self::LAZY_LOADING] = $lazy ? false : $options[self::LAZY_LOADING];
$inner = '';
$list[] = $var;
@@ -290,8 +301,11 @@ private static function dumpObject(&$var, array $options, int $level): string
}
array_pop($list);
return '<span class="tracy-toggle' . ($collapsed ? ' tracy-collapsed' : '') . '">' . $out . "</span>\n"
. '<div' . ($collapsed ? ' class="tracy-collapsed"' : '') . '>' . $inner . '</div>';
return '<span class="tracy-toggle' . ($collapsed ? ' tracy-collapsed' : '') . '">'. $out . "</span>\n"
. '<div'
. ($collapsed ? ' class="tracy-collapsed"' : '')
. ($lazy ? ' data-tracy-content="' . Helpers::escapeHtml($inner) . '"' : '')
. '>' . ($lazy ? '' : $inner) . '</div>';
} else {
return $out . " { ... }\n";
@@ -41,6 +41,11 @@
dest = ref[3] ? Toggle.nextElement(dest.nextElementSibling, ref[4]) : dest;
dest = ref[5] ? dest.querySelector(ref[5]) : dest;

if (dest.dataset.tracyContent) {
dest.innerHTML = dest.dataset.tracyContent;
delete dest.dataset.tracyContent;
}

el.classList.toggle('tracy-collapsed', !show);
dest.classList.toggle('tracy-collapsed', !show);

@@ -61,14 +61,14 @@ Assert::match('<pre class="tracy-dump"><span class="tracy-toggle"><span class="t
<div><span class="tracy-dump-indent"> | </span><span class="tracy-dump-key">0</span> => <span class="tracy-dump-number">1</span>
<span class="tracy-dump-indent"> | </span><span class="tracy-dump-key">1</span> => <span class="tracy-dump-number">2</span>
</div><span class="tracy-dump-indent"> </span><span class="tracy-dump-key">4</span> => <span class="tracy-toggle tracy-collapsed"><span class="tracy-dump-array">array</span> (7)</span>
<div class="tracy-collapsed"><span class="tracy-dump-indent"> | </span><span class="tracy-dump-key">1</span> => <span class="tracy-dump-number">1</span>
<span class="tracy-dump-indent"> | </span><span class="tracy-dump-key">2</span> => <span class="tracy-dump-number">2</span>
<span class="tracy-dump-indent"> | </span><span class="tracy-dump-key">3</span> => <span class="tracy-dump-number">3</span>
<span class="tracy-dump-indent"> | </span><span class="tracy-dump-key">4</span> => <span class="tracy-dump-number">4</span>
<span class="tracy-dump-indent"> | </span><span class="tracy-dump-key">5</span> => <span class="tracy-dump-number">5</span>
<span class="tracy-dump-indent"> | </span><span class="tracy-dump-key">6</span> => <span class="tracy-dump-number">6</span>
<span class="tracy-dump-indent"> | </span><span class="tracy-dump-key">7</span> => <span class="tracy-dump-number">7</span>
</div></div></pre>', Dumper::toHtml([1, 'hello', [], [1, 2], [1 => 1, 2, 3, 4, 5, 6, 7]]));
<div class="tracy-collapsed" data-tracy-content="&lt;span class=&quot;tracy-dump-indent&quot;&gt; | &lt;/span&gt;&lt;span class=&quot;tracy-dump-key&quot;&gt;1&lt;/span&gt; =&gt; &lt;span class=&quot;tracy-dump-number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;tracy-dump-indent&quot;&gt; | &lt;/span&gt;&lt;span class=&quot;tracy-dump-key&quot;&gt;2&lt;/span&gt; =&gt; &lt;span class=&quot;tracy-dump-number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;tracy-dump-indent&quot;&gt; | &lt;/span&gt;&lt;span class=&quot;tracy-dump-key&quot;&gt;3&lt;/span&gt; =&gt; &lt;span class=&quot;tracy-dump-number&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;tracy-dump-indent&quot;&gt; | &lt;/span&gt;&lt;span class=&quot;tracy-dump-key&quot;&gt;4&lt;/span&gt; =&gt; &lt;span class=&quot;tracy-dump-number&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;tracy-dump-indent&quot;&gt; | &lt;/span&gt;&lt;span class=&quot;tracy-dump-key&quot;&gt;5&lt;/span&gt; =&gt; &lt;span class=&quot;tracy-dump-number&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;tracy-dump-indent&quot;&gt; | &lt;/span&gt;&lt;span class=&quot;tracy-dump-key&quot;&gt;6&lt;/span&gt; =&gt; &lt;span class=&quot;tracy-dump-number&quot;&gt;6&lt;/span&gt;
&lt;span class=&quot;tracy-dump-indent&quot;&gt; | &lt;/span&gt;&lt;span class=&quot;tracy-dump-key&quot;&gt;7&lt;/span&gt; =&gt; &lt;span class=&quot;tracy-dump-number&quot;&gt;7&lt;/span&gt;
"></div></div></pre>', Dumper::toHtml([1, 'hello', [], [1, 2], [1 => 1, 2, 3, 4, 5, 6, 7]]));
Assert::match('<pre class="tracy-dump"><span class="tracy-toggle tracy-collapsed"><span class="tracy-dump-resource">stream resource</span> <span class="tracy-dump-hash">#%d%</span></span>
<div class="tracy-collapsed">%A%', Dumper::toHtml(fopen(__FILE__, 'r')));
@@ -86,35 +86,35 @@ Assert::match('<pre class="tracy-dump"><span class="tracy-toggle"><span class="t
Assert::match('<pre class="tracy-dump"><span class="tracy-toggle"><span class="tracy-dump-object">Test</span> <span class="tracy-dump-hash">#%a%</span></span>
<div><span class="tracy-dump-indent"> </span><span class="tracy-dump-key">x</span> => <span class="tracy-toggle tracy-collapsed"><span class="tracy-dump-array">array</span> (2)</span>
<div class="tracy-collapsed"><span class="tracy-dump-indent"> | </span><span class="tracy-dump-key">0</span> => <span class="tracy-dump-number">10</span>
<span class="tracy-dump-indent"> | </span><span class="tracy-dump-key">1</span> => <span class="tracy-dump-null">null</span>
</div><span class="tracy-dump-indent"> </span><span class="tracy-dump-key">y</span> <span class="tracy-dump-visibility">private</span> => <span class="tracy-dump-string">"hello"</span> (5)
<div class="tracy-collapsed" data-tracy-content="&lt;span class=&quot;tracy-dump-indent&quot;&gt; | &lt;/span&gt;&lt;span class=&quot;tracy-dump-key&quot;&gt;0&lt;/span&gt; =&gt; &lt;span class=&quot;tracy-dump-number&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;tracy-dump-indent&quot;&gt; | &lt;/span&gt;&lt;span class=&quot;tracy-dump-key&quot;&gt;1&lt;/span&gt; =&gt; &lt;span class=&quot;tracy-dump-null&quot;&gt;null&lt;/span&gt;
"></div><span class="tracy-dump-indent"> </span><span class="tracy-dump-key">y</span> <span class="tracy-dump-visibility">private</span> => <span class="tracy-dump-string">"hello"</span> (5)
<span class="tracy-dump-indent"> </span><span class="tracy-dump-key">z</span> <span class="tracy-dump-visibility">protected</span> => <span class="tracy-dump-number">30.0</span>
</div></pre>', Dumper::toHtml(new Test, [Dumper::COLLAPSE_COUNT => 1]));
Assert::match('<pre class="tracy-dump"><span class="tracy-toggle"><span class="tracy-dump-object">Test</span> <span class="tracy-dump-hash">#%a%</span></span>
<div><span class="tracy-dump-indent"> </span><span class="tracy-dump-key">x</span> => <span class="tracy-toggle tracy-collapsed"><span class="tracy-dump-array">array</span> (2)</span>
<div class="tracy-collapsed"><span class="tracy-dump-indent"> | </span><span class="tracy-dump-key">0</span> => <span class="tracy-dump-number">10</span>
<span class="tracy-dump-indent"> | </span><span class="tracy-dump-key">1</span> => <span class="tracy-dump-null">null</span>
</div><span class="tracy-dump-indent"> </span><span class="tracy-dump-key">y</span> <span class="tracy-dump-visibility">private</span> => <span class="tracy-dump-string">"hello"</span> (5)
<div class="tracy-collapsed" data-tracy-content="&lt;span class=&quot;tracy-dump-indent&quot;&gt; | &lt;/span&gt;&lt;span class=&quot;tracy-dump-key&quot;&gt;0&lt;/span&gt; =&gt; &lt;span class=&quot;tracy-dump-number&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;tracy-dump-indent&quot;&gt; | &lt;/span&gt;&lt;span class=&quot;tracy-dump-key&quot;&gt;1&lt;/span&gt; =&gt; &lt;span class=&quot;tracy-dump-null&quot;&gt;null&lt;/span&gt;
"></div><span class="tracy-dump-indent"> </span><span class="tracy-dump-key">y</span> <span class="tracy-dump-visibility">private</span> => <span class="tracy-dump-string">"hello"</span> (5)
<span class="tracy-dump-indent"> </span><span class="tracy-dump-key">z</span> <span class="tracy-dump-visibility">protected</span> => <span class="tracy-dump-number">30.0</span>
</div></pre>', Dumper::toHtml(new Test, [Dumper::COLLAPSE_COUNT => 1, Dumper::COLLAPSE => false]));
Assert::match('<pre class="tracy-dump"><span class="tracy-toggle tracy-collapsed"><span class="tracy-dump-object">Test</span> <span class="tracy-dump-hash">#%a%</span></span>
<div class="tracy-collapsed"><span class="tracy-dump-indent"> </span><span class="tracy-dump-key">x</span> => <span class="tracy-toggle"><span class="tracy-dump-array">array</span> (2)</span>
<div><span class="tracy-dump-indent"> | </span><span class="tracy-dump-key">0</span> => <span class="tracy-dump-number">10</span>
<span class="tracy-dump-indent"> | </span><span class="tracy-dump-key">1</span> => <span class="tracy-dump-null">null</span>
</div><span class="tracy-dump-indent"> </span><span class="tracy-dump-key">y</span> <span class="tracy-dump-visibility">private</span> => <span class="tracy-dump-string">"hello"</span> (5)
<span class="tracy-dump-indent"> </span><span class="tracy-dump-key">z</span> <span class="tracy-dump-visibility">protected</span> => <span class="tracy-dump-number">30.0</span>
</div></pre>', Dumper::toHtml(new Test, [Dumper::COLLAPSE => true]));
<div class="tracy-collapsed" data-tracy-content="&lt;span class=&quot;tracy-dump-indent&quot;&gt; &lt;/span&gt;&lt;span class=&quot;tracy-dump-key&quot;&gt;x&lt;/span&gt; =&gt; &lt;span class=&quot;tracy-toggle&quot;&gt;&lt;span class=&quot;tracy-dump-array&quot;&gt;array&lt;/span&gt; (2)&lt;/span&gt;
&lt;div&gt;&lt;span class=&quot;tracy-dump-indent&quot;&gt; | &lt;/span&gt;&lt;span class=&quot;tracy-dump-key&quot;&gt;0&lt;/span&gt; =&gt; &lt;span class=&quot;tracy-dump-number&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;tracy-dump-indent&quot;&gt; | &lt;/span&gt;&lt;span class=&quot;tracy-dump-key&quot;&gt;1&lt;/span&gt; =&gt; &lt;span class=&quot;tracy-dump-null&quot;&gt;null&lt;/span&gt;
&lt;/div&gt;&lt;span class=&quot;tracy-dump-indent&quot;&gt; &lt;/span&gt;&lt;span class=&quot;tracy-dump-key&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;tracy-dump-visibility&quot;&gt;private&lt;/span&gt; =&gt; &lt;span class=&quot;tracy-dump-string&quot;&gt;&quot;hello&quot;&lt;/span&gt; (5)
&lt;span class=&quot;tracy-dump-indent&quot;&gt; &lt;/span&gt;&lt;span class=&quot;tracy-dump-key&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;tracy-dump-visibility&quot;&gt;protected&lt;/span&gt; =&gt; &lt;span class=&quot;tracy-dump-number&quot;&gt;30.0&lt;/span&gt;
"></div></pre>', Dumper::toHtml(new Test, [Dumper::COLLAPSE => true]));
Assert::match('<pre class="tracy-dump"><span class="tracy-toggle tracy-collapsed"><span class="tracy-dump-object">Test</span> <span class="tracy-dump-hash">#%a%</span></span>
<div class="tracy-collapsed"><span class="tracy-dump-indent"> </span><span class="tracy-dump-key">x</span> => <span class="tracy-toggle"><span class="tracy-dump-array">array</span> (2)</span>
<div><span class="tracy-dump-indent"> | </span><span class="tracy-dump-key">0</span> => <span class="tracy-dump-number">10</span>
<span class="tracy-dump-indent"> | </span><span class="tracy-dump-key">1</span> => <span class="tracy-dump-null">null</span>
</div><span class="tracy-dump-indent"> </span><span class="tracy-dump-key">y</span> <span class="tracy-dump-visibility">private</span> => <span class="tracy-dump-string">"hello"</span> (5)
<span class="tracy-dump-indent"> </span><span class="tracy-dump-key">z</span> <span class="tracy-dump-visibility">protected</span> => <span class="tracy-dump-number">30.0</span>
</div></pre>', Dumper::toHtml(new Test, [Dumper::COLLAPSE => 3]));
<div class="tracy-collapsed" data-tracy-content="&lt;span class=&quot;tracy-dump-indent&quot;&gt; &lt;/span&gt;&lt;span class=&quot;tracy-dump-key&quot;&gt;x&lt;/span&gt; =&gt; &lt;span class=&quot;tracy-toggle&quot;&gt;&lt;span class=&quot;tracy-dump-array&quot;&gt;array&lt;/span&gt; (2)&lt;/span&gt;
&lt;div&gt;&lt;span class=&quot;tracy-dump-indent&quot;&gt; | &lt;/span&gt;&lt;span class=&quot;tracy-dump-key&quot;&gt;0&lt;/span&gt; =&gt; &lt;span class=&quot;tracy-dump-number&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;tracy-dump-indent&quot;&gt; | &lt;/span&gt;&lt;span class=&quot;tracy-dump-key&quot;&gt;1&lt;/span&gt; =&gt; &lt;span class=&quot;tracy-dump-null&quot;&gt;null&lt;/span&gt;
&lt;/div&gt;&lt;span class=&quot;tracy-dump-indent&quot;&gt; &lt;/span&gt;&lt;span class=&quot;tracy-dump-key&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;tracy-dump-visibility&quot;&gt;private&lt;/span&gt; =&gt; &lt;span class=&quot;tracy-dump-string&quot;&gt;&quot;hello&quot;&lt;/span&gt; (5)
&lt;span class=&quot;tracy-dump-indent&quot;&gt; &lt;/span&gt;&lt;span class=&quot;tracy-dump-key&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;tracy-dump-visibility&quot;&gt;protected&lt;/span&gt; =&gt; &lt;span class=&quot;tracy-dump-number&quot;&gt;30.0&lt;/span&gt;
"></div></pre>', Dumper::toHtml(new Test, [Dumper::COLLAPSE => 3]));
Assert::match('<pre class="tracy-dump"><span class="tracy-toggle"><span class="tracy-dump-object">Closure</span> <span class="tracy-dump-hash">#%a%</span></span>
<div><span class="tracy-dump-indent"> </span><span class="tracy-dump-key">file</span> => <span class="tracy-dump-string">"%a%"</span> (%i%)

0 comments on commit 9527a62

Please sign in to comment.