@@ -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" %s)</script> ' ;
28+ protected $ dumpSuffix = '</pre><script>Sfdump(%s)</script> ' ;
2929 protected $ dumpId = 'sf-dump ' ;
3030 protected $ colors = true ;
3131 protected $ headerIsDumped = false ;
@@ -43,16 +43,13 @@ class HtmlDumper extends CliDumper
4343 'meta ' => 'color:#B729D9 ' ,
4444 'key ' => 'color:#56DB3A ' ,
4545 'index ' => 'color:#1299DA ' ,
46- 'str .max-string-length b ' => 'color:#A0A0A0 ' ,
4746 );
4847
49- protected $ displayOptions = array (
50- 'initDepth ' => 1 ,
48+ private $ displayOptions = array (
5149 'maxDepth ' => 1 ,
5250 'maxStringLength ' => 160 ,
5351 );
54-
55- protected $ displayOptionsIsUpdated = false ;
52+ private $ extraDisplayOptions = array ();
5653
5754 /**
5855 * {@inheritdoc}
@@ -87,15 +84,12 @@ public function setStyles(array $styles)
8784 /**
8885 * Configures display options.
8986 *
90- * @param array $displayOptions A map of displayOptions names to customize the behavior.
87+ * @param array $displayOptions A map of display options to customize the behavior.
9188 */
9289 public function setDisplayOptions (array $ displayOptions )
9390 {
94- if ($ displayOptions )
95- {
96- $ this ->displayOptionsIsUpdated = true ;
97- $ this ->displayOptions = $ displayOptions + $ this ->displayOptions ;
98- }
91+ $ this ->headerIsDumped = false ;
92+ $ this ->displayOptions = $ displayOptions + $ this ->displayOptions ;
9993 }
10094
10195 /**
@@ -123,9 +117,9 @@ public function setDumpBoundaries($prefix, $suffix)
123117 /**
124118 * {@inheritdoc}
125119 */
126- public function dump (Data $ data , $ output = null , array $ displayOptions = [] )
120+ public function dump (Data $ data , $ output = null , array $ extraDisplayOptions = array () )
127121 {
128- $ this ->setDisplayOptions ( $ displayOptions ) ;
122+ $ this ->extraDisplayOptions = $ extraDisplayOptions ;
129123 parent ::dump ($ data , $ output );
130124 $ this ->dumpId = 'sf-dump- ' .mt_rand ();
131125 }
@@ -141,7 +135,7 @@ protected function getDumpHeader()
141135 return $ this ->dumpHeader ;
142136 }
143137
144- $ line = <<<'EOHTML'
138+ $ line = str_replace ( ' {$options} ' , json_encode ( $ this -> displayOptions , JSON_FORCE_OBJECT ), <<<'EOHTML'
145139<script>
146140Sfdump = window.Sfdump || (function (doc) {
147141
@@ -165,8 +159,8 @@ protected function getDumpHeader()
165159 };
166160}
167161
168- function toggle(a, depth ) {
169- var s = a.nextSibling || {}, oldClass = s.className, arrow, newClass, i ;
162+ function toggle(a, recursive ) {
163+ var s = a.nextSibling || {}, oldClass = s.className, arrow, newClass;
170164
171165 if ('sf-dump-compact' == oldClass) {
172166 arrow = '▼';
@@ -181,21 +175,13 @@ function toggle(a, depth) {
181175 a.lastChild.innerHTML = arrow;
182176 s.className = newClass;
183177
184- if (depth) {
185-
178+ if (recursive) {
186179 try {
187180 a = s.querySelectorAll('.'+oldClass);
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;
181+ for (s = 0; s < a.length; ++s) {
182+ if (a[s].className !== newClass) {
183+ a[s].className = newClass;
184+ a[s].previousSibling.lastChild.innerHTML = arrow;
199185 }
200186 }
201187 } catch (e) {
@@ -205,26 +191,9 @@ function toggle(a, depth) {
205191 return true;
206192};
207193
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) {
194+ return function (root, x) {
222195 root = doc.getElementById(root);
223- EOHTML;
224-
225- $ line .= 'options = options || ' .json_encode ($ this ->displayOptions ).'; ' ;
226196
227- $ line .= <<<'EOHTML'
228197 function a(e, f) {
229198 addEventListener(root, e, function (e) {
230199 if ('A' == e.target.tagName) {
@@ -253,8 +222,7 @@ function isCtrlKey(e) {
253222 a('click', function (a, e) {
254223 if (/\bsf-dump-toggle\b/.test(a.className)) {
255224 e.preventDefault();
256- var maxDepth = isCtrlKey(e) ? 'ALL' : options.maxDepth ;
257- if (!toggle(a, maxDepth)) {
225+ if (!toggle(a, isCtrlKey(e))) {
258226 var r = doc.getElementById(a.getAttribute('href').substr(1)),
259227 s = r.previousSibling,
260228 f = r.parentNode,
@@ -268,7 +236,7 @@ function isCtrlKey(e) {
268236 r.innerHTML = r.innerHTML.replace(new RegExp('^'+f[0].replace(rxEsc, '\\$1'), 'mg'), t[0]);
269237 }
270238 if ('sf-dump-compact' == r.className) {
271- toggle(s, maxDepth );
239+ toggle(s, isCtrlKey(e) );
272240 }
273241 }
274242
@@ -281,31 +249,37 @@ function isCtrlKey(e) {
281249 } else {
282250 doc.selection.empty();
283251 }
252+ } else if (/\bsf-dump-str-toggle\b/.test(a.className)) {
253+ e.preventDefault();
254+ e = a.parentNode.parentNode;
255+ e.className = e.className.replace(/sf-dump-str-(expand|collapse)/, a.parentNode.className);
284256 }
285257 });
286258
287259 var indentRx = new RegExp('^('+(root.getAttribute('data-indent-pad') || ' ').replace(rxEsc, '\\$1')+')+', 'm'),
260+ options = {$options},
288261 elt = root.getElementsByTagName('A'),
289262 len = elt.length,
290- i = 0,
291- t = [],
292- temp;
263+ i = 0, s, h,
264+ t = [];
293265
294266 while (i < len) t.push(elt[i++]);
295267
268+ for (i in x) {
269+ options[i] = x[i];
270+ }
271+
296272 elt = root.getElementsByTagName('SAMP');
297273 len = elt.length;
298274 i = 0;
299275
300276 while (i < len) t.push(elt[i++]);
301-
302277 len = t.length;
303- i = 0;
304278
305- while (i < len) {
279+ for (i = 0; i < len; ++i ) {
306280 elt = t[i];
307- if (" SAMP" == elt.tagName) {
308- elt.className = " sf-dump-expanded" ;
281+ if (' SAMP' == elt.tagName) {
282+ elt.className = ' sf-dump-expanded' ;
309283 a = elt.previousSibling || {};
310284 if ('A' != a.tagName) {
311285 a = doc.createElement('A');
@@ -317,19 +291,24 @@ function isCtrlKey(e) {
317291 a.title = (a.title ? a.title+'\n[' : '[')+keyHint+'+click] Expand all children';
318292 a.innerHTML += '<span>▼</span>';
319293 a.className += ' sf-dump-toggle';
320- if (getLevelNodeForParent(root, a) > options.initDepth) {
321- toggle(a);
294+ x = 1;
295+ if ('sf-dump' != elt.parentNode.className) {
296+ x += elt.parentNode.getAttribute('data-depth')/1;
297+ if (x > options.maxDepth) {
298+ toggle(a);
299+ }
322300 }
323- } else if ("sf-dump-ref" == elt.className && (a = elt.getAttribute('href'))) {
301+ elt.setAttribute('data-depth', x);
302+ } else if ('sf-dump-ref' == elt.className && (a = elt.getAttribute('href'))) {
324303 a = a.substr(1);
325304 elt.className += ' '+a;
326305
327306 if (/[\[{]$/.test(elt.previousSibling.nodeValue)) {
328307 a = a != elt.nextSibling.id && doc.getElementById(a);
329308 try {
330- t = a.nextSibling;
309+ s = a.nextSibling;
331310 elt.appendChild(a);
332- t .parentNode.insertBefore(a, t );
311+ s .parentNode.insertBefore(a, s );
333312 if (/^[@#]/.test(elt.innerHTML)) {
334313 elt.innerHTML += ' <span>▶</span>';
335314 } else {
@@ -345,43 +324,33 @@ function isCtrlKey(e) {
345324 }
346325 }
347326 }
348- ++i;
349327 }
350328
351- if (options.maxStringLength) {
352- configureMaxStringCollapse() ;
329+ if (0 >= options.maxStringLength) {
330+ return ;
353331 }
332+ try {
333+ elt = root.querySelectorAll('.sf-dump-str');
334+ len = elt.length;
335+ i = 0;
336+ t = [];
354337
355- function configureMaxStringCollapse()
356- {
357- var t = root.querySelectorAll('.sf-dump-str'), i = 0;
338+ while (i < len) t.push(elt[i++]);
339+ len = t.length;
358340
359- for (i = 0; i < t.length ; ++i) {
341+ for (i = 0; i < len ; ++i) {
360342 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';
343+ s = elt.innerText || elt.textContent;
344+ x = s.length - options.maxStringLength;
345+ if (0 < x) {
346+ h = elt.innerHTML;
347+ elt[elt.innerText ? 'innerText' : 'textContent'] = s.substring(0, options.maxStringLength);
348+ elt.className += ' sf-dump-str-collapse';
349+ elt.innerHTML = '<span class=sf-dump-str-collapse>'+h+'<a class="sf-dump-ref sf-dump-str-toggle" title="Collapse"> ◀</a></span>'+
350+ '<span class=sf-dump-str-expand>'+elt.innerHTML+'<a class="sf-dump-ref sf-dump-str-toggle" title="'+x+' remaining characters"> ▶</a></span>';
383351 }
384352 }
353+ } catch (e) {
385354 }
386355};
387356
@@ -410,16 +379,14 @@ function toggleMaxStringLength(elt) {
410379 border: 0;
411380 outline: none;
412381}
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
382+ .sf-dump-str-collapse .sf-dump-str-collapse {
383+ display: none;
418384}
419- pre .sf-dump .max-string-length b {
420- cursor: pointer ;
385+ .sf-dump-str-expand .sf-dump-str-expand {
386+ display: none ;
421387}
422- EOHTML;
388+ EOHTML
389+ );
423390
424391 foreach ($ this ->styles as $ class => $ style ) {
425392 $ line .= 'pre.sf-dump ' .('default ' !== $ class ? ' .sf-dump- ' .$ class : '' ).'{ ' .$ style .'} ' ;
@@ -533,11 +500,12 @@ protected function dumpLine($depth, $endOfValue = false)
533500 }
534501
535502 if (-1 === $ depth ) {
536- $ this ->line .= sprintf (
537- $ this ->dumpSuffix ,
538- $ this ->dumpId ,
539- $ this ->displayOptionsIsUpdated ? ', ' .json_encode ($ this ->displayOptions ) : ''
540- );
503+ $ args = array ('" ' .$ this ->dumpId .'" ' );
504+ if ($ this ->extraDisplayOptions ) {
505+ $ args [] = json_encode ($ this ->extraDisplayOptions , JSON_FORCE_OBJECT );
506+ }
507+ // Replace is for BC
508+ $ this ->line .= sprintf (str_replace ('"%s" ' , '%s ' , $ this ->dumpSuffix ), implode (', ' , $ args ));
541509 }
542510 $ this ->lastDepth = $ depth ;
543511
0 commit comments