3 * $Revision: 1.2 $ $Date: 2003/02/07 16:04:19 $
\r
6 /* ***** BEGIN LICENSE BLOCK *****
\r
7 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
\r
9 * The contents of this file are subject to the Mozilla Public License Version
\r
10 * 1.1 (the "License"); you may not use this file except in compliance with
\r
11 * the License. You may obtain a copy of the License at
\r
12 * http://www.mozilla.org/MPL/
\r
14 * Software distributed under the License is distributed on an "AS IS" basis,
\r
15 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
\r
16 * for the specific language governing rights and limitations under the
\r
19 * The Original Code is Netscape code.
\r
21 * The Initial Developer of the Original Code is
\r
22 * Netscape Corporation.
\r
23 * Portions created by the Initial Developer are Copyright (C) 2001
\r
24 * the Initial Developer. All Rights Reserved.
\r
26 * Contributor(s): Bob Clary <bclary@netscape.com>
\r
28 * ***** END LICENSE BLOCK ***** */
\r
33 2002-02-25: bclary - modified xbDebugTraceOject to make sure
\r
34 that original versions of wrapped functions were not
\r
35 rewrapped. This had caused an infinite loop in IE.
\r
37 2002-02-07: bclary - modified xbDebug.prototype.close to not null
\r
38 the debug window reference. This can cause problems with
\r
39 Internet Explorer if the page is refreshed. These issues will
\r
40 be addressed at a later date.
\r
46 this.stack = new Array();
\r
47 this.debugwindow = null;
\r
48 this.execprofile = new Object();
\r
51 xbDebug.prototype.push = function ()
\r
53 this.stack[this.stack.length] = this.on;
\r
57 xbDebug.prototype.pop = function ()
\r
59 this.on = this.stack[this.stack.length - 1];
\r
60 --this.stack.length;
\r
63 xbDebug.prototype.open = function ()
\r
65 if (this.debugwindow && !this.debugwindow.closed)
\r
68 this.debugwindow = window.open('about:blank', 'DEBUGWINDOW', 'height=400,width=600,resizable=yes,scrollbars=yes');
\r
69 this.debugwindow.moveTo(0,0);
\r
72 this.debugwindow.document.write('<html><head><title>xbDebug Window</title></head><body><h3>Javascript Debug Window</h3></body></html>');
\r
75 xbDebug.prototype.close = function ()
\r
77 if (!this.debugwindow)
\r
80 if (!this.debugwindow.closed)
\r
81 this.debugwindow.close();
\r
83 // bc 2002-02-07, other windows may still hold a reference to this: this.debugwindow = null;
\r
86 xbDebug.prototype.dump = function (msg)
\r
91 if (!this.debugwindow || this.debugwindow.closed)
\r
94 this.debugwindow.document.write(msg + '<br>');
\r
99 var xbDEBUG = new xbDebug();
\r
101 window.onunload = function () { xbDEBUG.close(); }
\r
103 function xbDebugGetFunctionName(funcref)
\r
112 return funcref.name;
\r
114 var name = funcref + '';
\r
115 name = name.substring(name.indexOf(' ') + 1, name.indexOf('('));
\r
116 funcref.name = name;
\r
118 if (!name) alert('name not defined');
\r
123 // emulate functionref.apply for IE mac and IE win < 5.5
\r
124 function xbDebugApplyFunction(funcname, funcref, thisref, argumentsref)
\r
130 alert('xbDebugApplyFunction: funcref is null');
\r
133 if (typeof(funcref.apply) != 'undefined')
\r
134 return funcref.apply(thisref, argumentsref);
\r
136 var applyexpr = 'thisref.xbDebug_orig_' + funcname + '(';
\r
139 for (i = 0; i < argumentsref.length; i++)
\r
141 applyexpr += 'argumentsref[' + i + '],';
\r
144 if (argumentsref.length > 0)
\r
146 applyexpr = applyexpr.substring(0, applyexpr.length - 1);
\r
151 return eval(applyexpr);
\r
154 function xbDebugCreateFunctionWrapper(scopename, funcname, precall, postcall)
\r
157 var scopeobject = eval(scopename);
\r
158 var funcref = scopeobject[funcname];
\r
160 scopeobject['xbDebug_orig_' + funcname] = funcref;
\r
162 wrappedfunc = function ()
\r
166 precall(scopename, funcname, arguments);
\r
167 rv = xbDebugApplyFunction(funcname, funcref, scopeobject, arguments);
\r
168 postcall(scopename, funcname, arguments, rv);
\r
172 if (typeof(funcref.constructor) != 'undefined')
\r
173 wrappedfunc.constructor = funcref.constuctor;
\r
175 if (typeof(funcref.prototype) != 'undefined')
\r
176 wrappedfunc.prototype = funcref.prototype;
\r
178 scopeobject[funcname] = wrappedfunc;
\r
181 function xbDebugCreateMethodWrapper(contextname, classname, methodname, precall, postcall)
\r
183 var context = eval(contextname);
\r
184 var methodref = context[classname].prototype[methodname];
\r
186 context[classname].prototype['xbDebug_orig_' + methodname] = methodref;
\r
188 var wrappedmethod = function ()
\r
191 // eval 'this' at method run time to pick up reference to the object's instance
\r
192 var thisref = eval('this');
\r
193 // eval 'arguments' at method run time to pick up method's arguments
\r
194 var argsref = arguments;
\r
196 precall(contextname + '.' + classname, methodname, argsref);
\r
197 rv = xbDebugApplyFunction(methodname, methodref, thisref, argsref);
\r
198 postcall(contextname + '.' + classname, methodname, argsref, rv);
\r
202 return wrappedmethod;
\r
205 function xbDebugPersistToString(obj)
\r
212 switch(typeof(obj))
\r
217 return '"' + obj + '"';
\r
219 return 'undefined';
\r
224 if (obj.constructor)
\r
225 return '[' + xbDebugGetFunctionName(obj.constructor) + ']';
\r
230 function xbDebugTraceBefore(scopename, funcname, funcarguments)
\r
234 var execprofile = xbDEBUG.execprofile[scopename + '.' + funcname];
\r
236 execprofile = xbDEBUG.execprofile[scopename + '.' + funcname] = { started: 0, time: 0, count: 0 };
\r
238 for (i = 0; i < funcarguments.length; i++)
\r
240 s += xbDebugPersistToString(funcarguments[i]);
\r
241 if (i < funcarguments.length - 1)
\r
245 xbDEBUG.dump('enter ' + scopename + '.' + funcname + '(' + s + ')');
\r
246 execprofile.started = (new Date()).getTime();
\r
249 function xbDebugTraceAfter(scopename, funcname, funcarguments, rv)
\r
253 var execprofile = xbDEBUG.execprofile[scopename + '.' + funcname];
\r
255 xbDEBUG.dump('xbDebugTraceAfter: execprofile not created for ' + scopename + '.' + funcname);
\r
256 else if (execprofile.started == 0)
\r
257 xbDEBUG.dump('xbDebugTraceAfter: execprofile.started == 0 for ' + scopename + '.' + funcname);
\r
260 execprofile.time += (new Date()).getTime() - execprofile.started;
\r
261 execprofile.count++;
\r
262 execprofile.started = 0;
\r
265 for (i = 0; i < funcarguments.length; i++)
\r
267 s += xbDebugPersistToString(funcarguments[i]);
\r
268 if (i < funcarguments.length - 1)
\r
272 xbDEBUG.dump('exit ' + scopename + '.' + funcname + '(' + s + ')==' + xbDebugPersistToString(rv));
\r
275 function xbDebugTraceFunction(scopename, funcname)
\r
277 xbDebugCreateFunctionWrapper(scopename, funcname, xbDebugTraceBefore, xbDebugTraceAfter);
\r
280 function xbDebugTraceObject(contextname, classname)
\r
282 var classref = eval(contextname + '.' + classname);
\r
286 if (!classref || !classref.prototype)
\r
289 for (p in classref.prototype)
\r
292 if (typeof(classref.prototype[sp]) == 'function' && (sp).indexOf('xbDebug_orig') == -1)
\r
294 classref.prototype[sp] = xbDebugCreateMethodWrapper(contextname, classname, sp, xbDebugTraceBefore, xbDebugTraceAfter);
\r
299 function xbDebugDumpProfile()
\r
305 for (p in xbDEBUG.execprofile)
\r
307 execprofile = xbDEBUG.execprofile[p];
\r
308 avg = Math.round ( 100 * execprofile.time/execprofile.count) /100;
\r
309 xbDEBUG.dump('Execution profile ' + p + ' called ' + execprofile.count + ' times. Total time=' + execprofile.time + 'ms. Avg Time=' + avg + 'ms.');
\r