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