Skip to content

Commit 58eb665

Browse files
MGDSoftnicolas-grekas
authored andcommitted
[VarDumper] Add maxDepth & maxStringLength display options
1 parent 06f5c86 commit 58eb665

File tree

1 file changed

+117
-18
lines changed

1 file changed

+117
-18
lines changed

src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php

Lines changed: 117 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class HtmlDumper extends CliDumper
2525

2626
protected $dumpHeader;
2727
protected $dumpPrefix = '<pre class=sf-dump id=%s data-indent-pad="%s">';
28-
protected $dumpSuffix = '</pre><script>Sfdump("%s")</script>';
28+
protected $dumpSuffix = '</pre><script>Sfdump("%s"%s)</script>';
2929
protected $dumpId = 'sf-dump';
3030
protected $colors = true;
3131
protected $headerIsDumped = false;
@@ -43,8 +43,17 @@ class HtmlDumper extends CliDumper
4343
'meta' => 'color:#B729D9',
4444
'key' => 'color:#56DB3A',
4545
'index' => 'color:#1299DA',
46+
'str .max-string-length b' => 'color:#A0A0A0',
4647
);
4748

49+
protected $displayOptions = array(
50+
'initDepth' => 1,
51+
'maxDepth' => 1,
52+
'maxStringLength' => 160,
53+
);
54+
55+
protected $displayOptionsIsUpdated = false;
56+
4857
/**
4958
* {@inheritdoc}
5059
*/
@@ -75,6 +84,20 @@ public function setStyles(array $styles)
7584
$this->styles = $styles + $this->styles;
7685
}
7786

87+
/**
88+
* Configures display options.
89+
*
90+
* @param array $displayOptions A map of displayOptions names to customize the behavior.
91+
*/
92+
public function setDisplayOptions(array $displayOptions)
93+
{
94+
if ($displayOptions)
95+
{
96+
$this->displayOptionsIsUpdated = true;
97+
$this->displayOptions = $displayOptions + $this->displayOptions;
98+
}
99+
}
100+
78101
/**
79102
* Sets an HTML header that will be dumped once in the output stream.
80103
*
@@ -100,8 +123,9 @@ public function setDumpBoundaries($prefix, $suffix)
100123
/**
101124
* {@inheritdoc}
102125
*/
103-
public function dump(Data $data, $output = null)
126+
public function dump(Data $data, $output = null, array $displayOptions = [])
104127
{
128+
$this->setDisplayOptions($displayOptions);
105129
parent::dump($data, $output);
106130
$this->dumpId = 'sf-dump-'.mt_rand();
107131
}
@@ -141,8 +165,8 @@ protected function getDumpHeader()
141165
};
142166
}
143167
144-
function toggle(a, recursive) {
145-
var s = a.nextSibling || {}, oldClass = s.className, arrow, newClass;
168+
function toggle(a, depth) {
169+
var s = a.nextSibling || {}, oldClass = s.className, arrow, newClass, i;
146170
147171
if ('sf-dump-compact' == oldClass) {
148172
arrow = '▼';
@@ -157,13 +181,21 @@ function toggle(a, recursive) {
157181
a.lastChild.innerHTML = arrow;
158182
s.className = newClass;
159183
160-
if (recursive) {
184+
if (depth) {
185+
161186
try {
162187
a = s.querySelectorAll('.'+oldClass);
163-
for (s = 0; s < a.length; ++s) {
164-
if (a[s].className !== newClass) {
165-
a[s].className = newClass;
166-
a[s].previousSibling.lastChild.innerHTML = arrow;
188+
189+
for (i = 0; i < a.length; ++i) {
190+
if (depth != 'ALL' && isNaN(depth) == false) {
191+
if (getLevelNodeForParent(s, a[i]) >= depth) {
192+
continue;
193+
}
194+
}
195+
196+
if (a[i].className !== newClass) {
197+
a[i].className = newClass;
198+
a[i].previousSibling.lastChild.innerHTML = arrow;
167199
}
168200
}
169201
} catch (e) {
@@ -173,9 +205,26 @@ function toggle(a, recursive) {
173205
return true;
174206
};
175207
176-
return function (root) {
208+
function getLevelNodeForParent(parentNode, currentNode, level) {
209+
level = level || 0;
210+
level++;
211+
212+
if (parentNode.isSameNode(currentNode)) {
213+
return level-1;
214+
}
215+
216+
currentNode = currentNode.parentNode;
217+
218+
return getLevelNodeForParent(parentNode, currentNode, level);
219+
}
220+
221+
return function (root, options) {
177222
root = doc.getElementById(root);
223+
EOHTML;
224+
225+
$line .= 'options = options || '.json_encode($this->displayOptions).';';
178226

227+
$line .= <<<'EOHTML'
179228
function a(e, f) {
180229
addEventListener(root, e, function (e) {
181230
if ('A' == e.target.tagName) {
@@ -204,7 +253,8 @@ function isCtrlKey(e) {
204253
a('click', function (a, e) {
205254
if (/\bsf-dump-toggle\b/.test(a.className)) {
206255
e.preventDefault();
207-
if (!toggle(a, isCtrlKey(e))) {
256+
var maxDepth = isCtrlKey(e) ? 'ALL' : options.maxDepth ;
257+
if (!toggle(a, maxDepth)) {
208258
var r = doc.getElementById(a.getAttribute('href').substr(1)),
209259
s = r.previousSibling,
210260
f = r.parentNode,
@@ -218,7 +268,7 @@ function isCtrlKey(e) {
218268
r.innerHTML = r.innerHTML.replace(new RegExp('^'+f[0].replace(rxEsc, '\\$1'), 'mg'), t[0]);
219269
}
220270
if ('sf-dump-compact' == r.className) {
221-
toggle(s, isCtrlKey(e));
271+
toggle(s, maxDepth);
222272
}
223273
}
224274
@@ -238,7 +288,8 @@ function isCtrlKey(e) {
238288
elt = root.getElementsByTagName('A'),
239289
len = elt.length,
240290
i = 0,
241-
t = [];
291+
t = [],
292+
temp;
242293
243294
while (i < len) t.push(elt[i++]);
244295
@@ -248,12 +299,11 @@ function isCtrlKey(e) {
248299
249300
while (i < len) t.push(elt[i++]);
250301
251-
root = t;
252302
len = t.length;
253-
i = t = 0;
303+
i = 0;
254304
255305
while (i < len) {
256-
elt = root[i];
306+
elt = t[i];
257307
if ("SAMP" == elt.tagName) {
258308
elt.className = "sf-dump-expanded";
259309
a = elt.previousSibling || {};
@@ -267,7 +317,7 @@ function isCtrlKey(e) {
267317
a.title = (a.title ? a.title+'\n[' : '[')+keyHint+'+click] Expand all children';
268318
a.innerHTML += '<span>▼</span>';
269319
a.className += ' sf-dump-toggle';
270-
if ('sf-dump' != elt.parentNode.className) {
320+
if (getLevelNodeForParent(root, a) > options.initDepth) {
271321
toggle(a);
272322
}
273323
} else if ("sf-dump-ref" == elt.className && (a = elt.getAttribute('href'))) {
@@ -297,6 +347,42 @@ function isCtrlKey(e) {
297347
}
298348
++i;
299349
}
350+
351+
if (options.maxStringLength) {
352+
configureMaxStringCollapse();
353+
}
354+
355+
function configureMaxStringCollapse()
356+
{
357+
var t = root.querySelectorAll('.sf-dump-str'), i = 0;
358+
359+
for (i = 0; i < t.length; ++i) {
360+
elt = t[i];
361+
if (elt.innerText.length > options.maxStringLength) {
362+
elt.innerHTML = '<span class="max-string-length collapsed">' +
363+
'<span class="collapsed">' + elt.innerText.substring(0, options.maxStringLength)+'...' +' <b>[+]</b></span>'+
364+
'<span class="expanded">' + elt.innerHTML +' <b>[-]</b></span>' +
365+
'</span>';
366+
}
367+
}
368+
369+
t = root.querySelectorAll('.max-string-length span b');
370+
371+
for (i = 0; i < t.length; ++i) {
372+
t[i].addEventListener("click", function(e) {
373+
toggleMaxStringLength(e.target.parentNode.parentNode);
374+
});
375+
}
376+
377+
function toggleMaxStringLength(elt) {
378+
379+
if (elt.className == 'max-string-length expanded') {
380+
elt.className = 'max-string-length collapsed';
381+
}else{
382+
elt.className = 'max-string-length expanded';
383+
}
384+
}
385+
}
300386
};
301387
302388
})(document);
@@ -324,6 +410,15 @@ function isCtrlKey(e) {
324410
border: 0;
325411
outline: none;
326412
}
413+
pre.sf-dump .max-string-length.expanded .collapsed {
414+
display:none;
415+
}
416+
pre.sf-dump .max-string-length.collapsed .expanded {
417+
display:none
418+
}
419+
pre.sf-dump .max-string-length b {
420+
cursor: pointer;
421+
}
327422
EOHTML;
328423

329424
foreach ($this->styles as $class => $style) {
@@ -438,7 +533,11 @@ protected function dumpLine($depth, $endOfValue = false)
438533
}
439534

440535
if (-1 === $depth) {
441-
$this->line .= sprintf($this->dumpSuffix, $this->dumpId);
536+
$this->line .= sprintf(
537+
$this->dumpSuffix,
538+
$this->dumpId,
539+
$this->displayOptionsIsUpdated ? ','.json_encode($this->displayOptions) : ''
540+
);
442541
}
443542
$this->lastDepth = $depth;
444543

0 commit comments

Comments
 (0)