@@ -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+ }
327422EOHTML;
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