@@ -25,7 +25,7 @@ class HtmlDumper extends CliDumper
25
25
26
26
protected $ dumpHeader ;
27
27
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> ' ;
29
29
protected $ dumpId = 'sf-dump ' ;
30
30
protected $ colors = true ;
31
31
protected $ headerIsDumped = false ;
@@ -43,8 +43,17 @@ class HtmlDumper extends CliDumper
43
43
'meta ' => 'color:#B729D9 ' ,
44
44
'key ' => 'color:#56DB3A ' ,
45
45
'index ' => 'color:#1299DA ' ,
46
+ 'str .max-string-length b ' => 'color:#A0A0A0 ' ,
46
47
);
47
48
49
+ protected $ displayOptions = array (
50
+ 'initDepth ' => 1 ,
51
+ 'maxDepth ' => 1 ,
52
+ 'maxStringLength ' => 160 ,
53
+ );
54
+
55
+ protected $ displayOptionsIsUpdated = false ;
56
+
48
57
/**
49
58
* {@inheritdoc}
50
59
*/
@@ -75,6 +84,20 @@ public function setStyles(array $styles)
75
84
$ this ->styles = $ styles + $ this ->styles ;
76
85
}
77
86
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
+
78
101
/**
79
102
* Sets an HTML header that will be dumped once in the output stream.
80
103
*
@@ -100,8 +123,9 @@ public function setDumpBoundaries($prefix, $suffix)
100
123
/**
101
124
* {@inheritdoc}
102
125
*/
103
- public function dump (Data $ data , $ output = null )
126
+ public function dump (Data $ data , $ output = null , array $ displayOptions = [] )
104
127
{
128
+ $ this ->setDisplayOptions ($ displayOptions );
105
129
parent ::dump ($ data , $ output );
106
130
$ this ->dumpId = 'sf-dump- ' .mt_rand ();
107
131
}
@@ -141,8 +165,8 @@ protected function getDumpHeader()
141
165
};
142
166
}
143
167
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 ;
146
170
147
171
if ('sf-dump-compact' == oldClass) {
148
172
arrow = '▼';
@@ -157,13 +181,21 @@ function toggle(a, recursive) {
157
181
a.lastChild.innerHTML = arrow;
158
182
s.className = newClass;
159
183
160
- if (recursive) {
184
+ if (depth) {
185
+
161
186
try {
162
187
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;
167
199
}
168
200
}
169
201
} catch (e) {
@@ -173,9 +205,26 @@ function toggle(a, recursive) {
173
205
return true;
174
206
};
175
207
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) {
177
222
root = doc.getElementById(root);
223
+ EOHTML;
224
+
225
+ $ line .= 'options = options || ' .json_encode ($ this ->displayOptions ).'; ' ;
178
226
227
+ $ line .= <<<'EOHTML'
179
228
function a(e, f) {
180
229
addEventListener(root, e, function (e) {
181
230
if ('A' == e.target.tagName) {
@@ -204,7 +253,8 @@ function isCtrlKey(e) {
204
253
a('click', function (a, e) {
205
254
if (/\bsf-dump-toggle\b/.test(a.className)) {
206
255
e.preventDefault();
207
- if (!toggle(a, isCtrlKey(e))) {
256
+ var maxDepth = isCtrlKey(e) ? 'ALL' : options.maxDepth ;
257
+ if (!toggle(a, maxDepth)) {
208
258
var r = doc.getElementById(a.getAttribute('href').substr(1)),
209
259
s = r.previousSibling,
210
260
f = r.parentNode,
@@ -218,7 +268,7 @@ function isCtrlKey(e) {
218
268
r.innerHTML = r.innerHTML.replace(new RegExp('^'+f[0].replace(rxEsc, '\\$1'), 'mg'), t[0]);
219
269
}
220
270
if ('sf-dump-compact' == r.className) {
221
- toggle(s, isCtrlKey(e) );
271
+ toggle(s, maxDepth );
222
272
}
223
273
}
224
274
@@ -238,7 +288,8 @@ function isCtrlKey(e) {
238
288
elt = root.getElementsByTagName('A'),
239
289
len = elt.length,
240
290
i = 0,
241
- t = [];
291
+ t = [],
292
+ temp;
242
293
243
294
while (i < len) t.push(elt[i++]);
244
295
@@ -248,12 +299,11 @@ function isCtrlKey(e) {
248
299
249
300
while (i < len) t.push(elt[i++]);
250
301
251
- root = t;
252
302
len = t.length;
253
- i = t = 0;
303
+ i = 0;
254
304
255
305
while (i < len) {
256
- elt = root [i];
306
+ elt = t [i];
257
307
if ("SAMP" == elt.tagName) {
258
308
elt.className = "sf-dump-expanded";
259
309
a = elt.previousSibling || {};
@@ -267,7 +317,7 @@ function isCtrlKey(e) {
267
317
a.title = (a.title ? a.title+'\n[' : '[')+keyHint+'+click] Expand all children';
268
318
a.innerHTML += '<span>▼</span>';
269
319
a.className += ' sf-dump-toggle';
270
- if ('sf-dump' != elt.parentNode.className ) {
320
+ if (getLevelNodeForParent(root, a) > options.initDepth ) {
271
321
toggle(a);
272
322
}
273
323
} else if ("sf-dump-ref" == elt.className && (a = elt.getAttribute('href'))) {
@@ -297,6 +347,42 @@ function isCtrlKey(e) {
297
347
}
298
348
++i;
299
349
}
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
+ }
300
386
};
301
387
302
388
})(document);
@@ -324,6 +410,15 @@ function isCtrlKey(e) {
324
410
border: 0;
325
411
outline: none;
326
412
}
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
+ }
327
422
EOHTML;
328
423
329
424
foreach ($ this ->styles as $ class => $ style ) {
@@ -438,7 +533,11 @@ protected function dumpLine($depth, $endOfValue = false)
438
533
}
439
534
440
535
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
+ );
442
541
}
443
542
$ this ->lastDepth = $ depth ;
444
543
0 commit comments