Skip to content

[VarDumper] Add maxDepth & maxStringLength display options #18948

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 28, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 86 additions & 19 deletions src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class HtmlDumper extends CliDumper

protected $dumpHeader;
protected $dumpPrefix = '<pre class=sf-dump id=%s data-indent-pad="%s">';
protected $dumpSuffix = '</pre><script>Sfdump("%s")</script>';
protected $dumpSuffix = '</pre><script>Sfdump(%s)</script>';
protected $dumpId = 'sf-dump';
protected $colors = true;
protected $headerIsDumped = false;
Expand All @@ -45,6 +45,12 @@ class HtmlDumper extends CliDumper
'index' => 'color:#1299DA',
);

private $displayOptions = array(
'maxDepth' => 1,
'maxStringLength' => 160,
);
private $extraDisplayOptions = array();

/**
* {@inheritdoc}
*/
Expand Down Expand Up @@ -75,6 +81,17 @@ public function setStyles(array $styles)
$this->styles = $styles + $this->styles;
}

/**
* Configures display options.
*
* @param array $displayOptions A map of display options to customize the behavior.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no dot at the end

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahah, you've been doing that for a long time, working on a PR to fix that :)

*/
public function setDisplayOptions(array $displayOptions)
{
$this->headerIsDumped = false;
$this->displayOptions = $displayOptions + $this->displayOptions;
}

/**
* Sets an HTML header that will be dumped once in the output stream.
*
Expand All @@ -100,8 +117,9 @@ public function setDumpBoundaries($prefix, $suffix)
/**
* {@inheritdoc}
*/
public function dump(Data $data, $output = null)
public function dump(Data $data, $output = null, array $extraDisplayOptions = array())
{
$this->extraDisplayOptions = $extraDisplayOptions;
parent::dump($data, $output);
$this->dumpId = 'sf-dump-'.mt_rand();
}
Expand All @@ -117,7 +135,7 @@ protected function getDumpHeader()
return $this->dumpHeader;
}

$line = <<<'EOHTML'
$line = str_replace('{$options}', json_encode($this->displayOptions, JSON_FORCE_OBJECT), <<<'EOHTML'
<script>
Sfdump = window.Sfdump || (function (doc) {

Expand Down Expand Up @@ -173,7 +191,7 @@ function toggle(a, recursive) {
return true;
};

return function (root) {
return function (root, x) {
root = doc.getElementById(root);

function a(e, f) {
Expand Down Expand Up @@ -231,31 +249,37 @@ function isCtrlKey(e) {
} else {
doc.selection.empty();
}
} else if (/\bsf-dump-str-toggle\b/.test(a.className)) {
e.preventDefault();
e = a.parentNode.parentNode;
e.className = e.className.replace(/sf-dump-str-(expand|collapse)/, a.parentNode.className);
}
});

var indentRx = new RegExp('^('+(root.getAttribute('data-indent-pad') || ' ').replace(rxEsc, '\\$1')+')+', 'm'),
options = {$options},
elt = root.getElementsByTagName('A'),
len = elt.length,
i = 0,
i = 0, s, h,
t = [];

while (i < len) t.push(elt[i++]);

for (i in x) {
options[i] = x[i];
}

elt = root.getElementsByTagName('SAMP');
len = elt.length;
i = 0;

while (i < len) t.push(elt[i++]);

root = t;
len = t.length;
i = t = 0;

while (i < len) {
elt = root[i];
if ("SAMP" == elt.tagName) {
elt.className = "sf-dump-expanded";
for (i = 0; i < len; ++i) {
elt = t[i];
if ('SAMP' == elt.tagName) {
elt.className = 'sf-dump-expanded';
a = elt.previousSibling || {};
if ('A' != a.tagName) {
a = doc.createElement('A');
Expand All @@ -267,19 +291,24 @@ function isCtrlKey(e) {
a.title = (a.title ? a.title+'\n[' : '[')+keyHint+'+click] Expand all children';
a.innerHTML += '<span>▼</span>';
a.className += ' sf-dump-toggle';
x = 1;
if ('sf-dump' != elt.parentNode.className) {
toggle(a);
x += elt.parentNode.getAttribute('data-depth')/1;
if (x > options.maxDepth) {
toggle(a);
}
}
} else if ("sf-dump-ref" == elt.className && (a = elt.getAttribute('href'))) {
elt.setAttribute('data-depth', x);
} else if ('sf-dump-ref' == elt.className && (a = elt.getAttribute('href'))) {
a = a.substr(1);
elt.className += ' '+a;

if (/[\[{]$/.test(elt.previousSibling.nodeValue)) {
a = a != elt.nextSibling.id && doc.getElementById(a);
try {
t = a.nextSibling;
s = a.nextSibling;
elt.appendChild(a);
t.parentNode.insertBefore(a, t);
s.parentNode.insertBefore(a, s);
if (/^[@#]/.test(elt.innerHTML)) {
elt.innerHTML += ' <span>▶</span>';
} else {
Expand All @@ -295,7 +324,33 @@ function isCtrlKey(e) {
}
}
}
++i;
}

if (0 >= options.maxStringLength) {
return;
}
try {
elt = root.querySelectorAll('.sf-dump-str');
len = elt.length;
i = 0;
t = [];

while (i < len) t.push(elt[i++]);
len = t.length;

for (i = 0; i < len; ++i) {
elt = t[i];
s = elt.innerText || elt.textContent;
x = s.length - options.maxStringLength;
if (0 < x) {
h = elt.innerHTML;
elt[elt.innerText ? 'innerText' : 'textContent'] = s.substring(0, options.maxStringLength);
elt.className += ' sf-dump-str-collapse';
elt.innerHTML = '<span class=sf-dump-str-collapse>'+h+'<a class="sf-dump-ref sf-dump-str-toggle" title="Collapse"> ◀</a></span>'+
'<span class=sf-dump-str-expand>'+elt.innerHTML+'<a class="sf-dump-ref sf-dump-str-toggle" title="'+x+' remaining characters"> ▶</a></span>';
}
}
} catch (e) {
}
};

Expand Down Expand Up @@ -324,7 +379,14 @@ function isCtrlKey(e) {
border: 0;
outline: none;
}
EOHTML;
.sf-dump-str-collapse .sf-dump-str-collapse {
display: none;
}
.sf-dump-str-expand .sf-dump-str-expand {
display: none;
}
EOHTML
);

foreach ($this->styles as $class => $style) {
$line .= 'pre.sf-dump'.('default' !== $class ? ' .sf-dump-'.$class : '').'{'.$style.'}';
Expand Down Expand Up @@ -438,7 +500,12 @@ protected function dumpLine($depth, $endOfValue = false)
}

if (-1 === $depth) {
$this->line .= sprintf($this->dumpSuffix, $this->dumpId);
$args = array('"'.$this->dumpId.'"');
if ($this->extraDisplayOptions) {
$args[] = json_encode($this->extraDisplayOptions, JSON_FORCE_OBJECT);
}
// Replace is for BC
$this->line .= sprintf(str_replace('"%s"', '%s', $this->dumpSuffix), implode(', ', $args));
}
$this->lastDepth = $depth;

Expand Down