@@ -24,7 +24,7 @@ class HtmlDumper extends CliDumper
2424 public static $ defaultOutputStream = 'php://output ' ;
2525
2626 protected $ dumpHeader ;
27- protected $ dumpPrefix = '<pre id=%id% > ' ;
27+ protected $ dumpPrefix = '<pre class=sf-dump > ' ;
2828 protected $ dumpSuffix = '</pre><script>Sfjs.dump.instrument()</script> ' ;
2929 protected $ dumpId = 'sf-dump ' ;
3030 protected $ colors = true ;
@@ -101,7 +101,7 @@ protected function getDumpHeader()
101101 $ this ->headerIsDumped = true ;
102102
103103 if (null !== $ this ->dumpHeader ) {
104- return str_replace ( ' %id% ' , $ this ->dumpId , $ this -> dumpHeader ) ;
104+ return $ this ->dumpHeader ;
105105 }
106106
107107 $ line = <<<'EOHTML'
@@ -110,19 +110,81 @@ protected function getDumpHeader()
110110Sfjs.dump = Sfjs.dump || {};
111111Sfjs.dump.childElts = Sfjs.dump.childElts || document.getElementsByName('sf-dump-child');
112112Sfjs.dump.childLen = Sfjs.dump.childLen || 0;
113+ Sfjs.dump.refElts = Sfjs.dump.refElts || document.getElementsByName('sf-dump-ref');
114+ Sfjs.dump.refLen = Sfjs.dump.refLen || 0;
115+ if (!Sfjs.dump.refStyle) {
116+ Sfjs.dump.refStyle = document.createElement('style');
117+ document.documentElement.firstChild.appendChild(Sfjs.dump.refStyle);
118+ }
113119Sfjs.dump.instrument = Sfjs.dump.instrument || function () {
114- var elt,
115- i = this.childLen,
116- aCompact = '▶</a><span class="sf-dump-compact">',
117- aExpanded = '▼</a><span class="sf-dump-expanded">';
120+ var elt, i, ref;
118121
122+ i = this.childLen;
119123 this.childLen= this.childElts.length;
120124
121125 while (i < this.childLen) {
122126 elt = this.childElts[i];
123127 if ("" == elt.className) {
124128 elt.className = "sf-dump-child";
125- elt.innerHTML = '<a class=sf-dump-ref onclick="Sfjs.dump.toggle(this)">'+('sf-dump-0' == elt.parentNode.className ? aExpanded : aCompact)+elt.innerHTML+'</span>';
129+ elt.innerHTML = '<a class=sf-dump-ref onclick="Sfjs.dump.toggle(this)"><span>▼</span></a><span class="sf-dump-expanded">'+elt.innerHTML+'</span>';
130+ if ('sf-dump-expanded' == elt.parentNode.className) {
131+ if (elt.children[1].firstChild.nextSibling.id) {
132+ elt.firstChild.appendChild(elt.children[1].firstChild);
133+ elt.firstChild.appendChild(elt.children[1].firstChild);
134+ }
135+ Sfjs.dump.toggle(elt.firstChild);
136+ }
137+ }
138+ ++i;
139+ }
140+
141+ i = this.refLen;
142+ this.refLen= this.refElts.length;
143+
144+ function instrumentRef(elt) {
145+ var ref = elt.id;
146+
147+ if (elt.href) {
148+ ref = elt.getAttribute('href').substr(1);
149+ if ('@' == elt.innerHTML.charAt(0)) {
150+ elt.onclick = function() {
151+ var r = document.getElementById(ref).parentNode.parentNode,
152+ f = r && r.parentNode,
153+ t = elt.parentNode,
154+ c = elt.cloneNode(true);
155+ if (r && r.className == "sf-dump-child") {
156+ f.insertBefore(c, r);
157+ try {
158+ t.replaceChild(r, elt);
159+ f.replaceChild(elt, c);
160+ Sfjs.dump.refStyle.innerHTML = '';
161+ r = r.firstChild;
162+ c = r.nextSibling;
163+ if ('sf-dump-compact' == c.className) {
164+ Sfjs.dump.toggle(r);
165+ }
166+
167+ return false;
168+ } catch (e) {
169+ f.removeChild(c);
170+ }
171+ }
172+ };
173+ }
174+ }
175+ elt.className += ' '+ref;
176+ elt.onmouseover = function() {
177+ Sfjs.dump.refStyle.innerHTML = 'pre.sf-dump .'+ref+'{background-color: yellow; border-radius: 2px}';
178+ };
179+ elt.onmouseout = function() {
180+ Sfjs.dump.refStyle.innerHTML = '';
181+ };
182+ }
183+
184+ while (i < this.refLen) {
185+ elt = this.refElts[i];
186+ if ("sf-dump-ref" == elt.className) {
187+ instrumentRef(elt);
126188 }
127189 ++i;
128190 }
@@ -131,51 +193,47 @@ protected function getDumpHeader()
131193 var s = a.nextElementSibling;
132194
133195 if ('sf-dump-compact' == s.className) {
134- a.innerHTML = '▼';
196+ a.firstChild. innerHTML = '▼';
135197 s.className = 'sf-dump-expanded';
136198 } else {
137- a.innerHTML = '▶';
199+ a.firstChild. innerHTML = '▶';
138200 s.className = 'sf-dump-compact';
139201 }
140202};
141203</script>
142204<style>
143- #%id% {
205+ pre.sf-dump {
144206 display: block;
145207 background-color: #300a24;
146208 white-space: pre;
147209 line-height: 1.2em;
148210 color: #eee8d5;
149211 font: 12px monospace, sans-serif;
150212 padding: 5px;
213+ border-radius: 5px;
151214}
152- #%id% span {
215+ pre.sf-dump span {
153216 display: inline;
154217}
155- #%id% .sf-dump-compact {
218+ pre.sf-dump .sf-dump-compact {
156219 display: none;
157220}
158- #%id% abbr {
221+ pre.sf-dump abbr {
159222 text-decoration: none;
160223 border: none;
161224 cursor: help;
162225}
163- #%id% a {
226+ pre.sf-dump a {
164227 text-decoration: none;
165228 cursor: pointer;
166229}
167- #%id% a:hover {
168- text-decoration: underline;
169- }
170230EOHTML;
171231
172232 foreach ($ this ->styles as $ class => $ style ) {
173- $ line .= "#%id% .sf-dump-$ class { {$ style }} " ;
233+ $ line .= "pre.sf-dump .sf-dump-$ class { {$ style }} " ;
174234 }
175235
176- $ this ->dumpHeader = preg_replace ('/\s+/ ' , ' ' , $ line ).'</style> ' .$ this ->dumpHeader ;
177-
178- return str_replace ('%id% ' , $ this ->dumpId , $ this ->dumpHeader );
236+ return $ this ->dumpHeader = preg_replace ('/\s+/ ' , ' ' , $ line ).'</style> ' .$ this ->dumpHeader ;
179237 }
180238
181239 /**
@@ -214,9 +272,9 @@ protected function style($style, $val)
214272 if ('ref ' === $ style ) {
215273 $ ref = substr ($ val , 1 );
216274 if ('# ' === $ val [0 ]) {
217- return "<span class=sf-dump-ref id= \"{$ this ->dumpId }-ref $ ref \"> $ val</span> " ;
275+ return "<span class=sf-dump-ref name=sf-dump-ref id= \"{$ this ->dumpId }-ref $ ref \"> $ val</span> " ;
218276 } else {
219- return "<a class=sf-dump-ref href= \"# {$ this ->dumpId }-ref $ ref \"> $ val</a> " ;
277+ return "<a class=sf-dump-ref name=sf-dump-ref href= \"# {$ this ->dumpId }-ref $ ref \"> $ val</a> " ;
220278 }
221279 }
222280
@@ -231,7 +289,9 @@ protected function style($style, $val)
231289 }
232290 } elseif ('note ' === $ style ) {
233291 if (false !== $ c = strrpos ($ val , '\\' )) {
234- $ val = sprintf ('<abbr title="%s" class=sf-dump-%s>%s</abbr> ' , $ val , $ style , substr ($ val , $ c +1 ));
292+ return sprintf ('<abbr title="%s" class=sf-dump-%s>%s</abbr> ' , $ val , $ style , substr ($ val , $ c +1 ));
293+ } elseif (': ' === $ val [0 ]) {
294+ return sprintf ('<abbr title="Resource of type `%s`" class=sf-dump-%s>%s</abbr> ' , substr ($ val , 1 ), $ style , $ val );
235295 }
236296 }
237297
@@ -243,20 +303,15 @@ protected function style($style, $val)
243303 */
244304 protected function dumpLine ($ depth )
245305 {
246- switch ($ this ->lastDepth - $ depth ) {
247- case +1 : $ this ->line = '</span> ' .$ this ->line ; break ;
248- case -1 : $ this ->line = "<span class=sf-dump- $ depth> $ this ->line " ; break ;
249- }
250-
251306 if (-1 === $ this ->lastDepth ) {
252- $ this ->line = str_replace ( ' %id% ' , $ this ->dumpId , $ this -> dumpPrefix ) .$ this ->line ;
307+ $ this ->line = $ this ->dumpPrefix .$ this ->line ;
253308 }
254309 if (!$ this ->headerIsDumped ) {
255310 $ this ->line = $ this ->getDumpHeader ().$ this ->line ;
256311 }
257312
258313 if (-1 === $ depth ) {
259- $ this ->line .= str_replace ( ' %id% ' , $ this ->dumpId , $ this -> dumpSuffix ) ;
314+ $ this ->line .= $ this ->dumpSuffix ;
260315 parent ::dumpLine (0 );
261316 }
262317 $ this ->lastDepth = $ depth ;
0 commit comments