server/src/main/resources/_firebug/firebug.js.uncompressed.js
changeset 22 948283342245
equal deleted inserted replaced
21:b43dd87f7ffa 22:948283342245
       
     1 define("dojo/_firebug/firebug", [
       
     2 	"../_base/kernel",
       
     3 	"require",
       
     4 	"../_base/html",
       
     5 	"../sniff",
       
     6 	"../_base/array",
       
     7 	"../_base/lang",
       
     8 	"../_base/event",
       
     9 	"../_base/unload"], function(dojo, require, html, has){
       
    10 
       
    11 	// module:
       
    12 	//		dojo/_firebug/firebug
       
    13 	// summary:
       
    14 	//		Firebug Lite, the baby brother to Joe Hewitt's Firebug for Mozilla Firefox
       
    15 	// description:
       
    16 	//		Opens a console for logging, debugging, and error messages.
       
    17 	//		Contains partial functionality to Firebug. See function list below.
       
    18 	//
       
    19 	//		NOTE:
       
    20 	//		Firebug is a Firefox extension created by Joe Hewitt (see license). You do not need Dojo to run Firebug.
       
    21 	//		Firebug Lite is included in Dojo by permission from Joe Hewitt
       
    22 	//		If you are new to Firebug, or used to the Dojo 0.4 dojo.debug, you can learn Firebug
       
    23 	//		functionality by reading the function comments below or visiting http://www.getfirebug.com/docs.html
       
    24 	//
       
    25 	//		NOTE:
       
    26 	//		To test Firebug Lite in Firefox:
       
    27 	//
       
    28 	//		- FF2: set "console = null" before loading dojo and set djConfig.isDebug=true
       
    29 	//		- FF3: disable Firebug and set djConfig.isDebug=true
       
    30 	//
       
    31 	// example:
       
    32 	//		Supports inline objects in object inspector window (only simple trace of dom nodes, however)
       
    33 	//	|	console.log("my object", {foo:"bar"})
       
    34 	// example:
       
    35 	//		Option for console to open in popup window
       
    36 	//	|	var djConfig = {isDebug: true, popup:true };
       
    37 	// example:
       
    38 	//		Option for console height (ignored for popup)
       
    39 	//	|	var djConfig = {isDebug: true, debugHeight:100 }
       
    40 
       
    41 
       
    42 	var isNewIE = (/Trident/.test(window.navigator.userAgent));
       
    43 	if(isNewIE){
       
    44 		// Fixing IE's console
       
    45 		// IE doesn't insert space between arguments. How annoying.
       
    46 		var calls = ["log", "info", "debug", "warn", "error"];
       
    47 		for(var i=0;i<calls.length;i++){
       
    48 			var m = calls[i];
       
    49 			if(!console[m] ||console[m]._fake){
       
    50 				// IE9 doesn't have console.debug method, a fake one is added later
       
    51 				continue;
       
    52 			}
       
    53 			var n = "_"+calls[i];
       
    54 			console[n] = console[m];
       
    55 			console[m] = (function(){
       
    56 				var type = n;
       
    57 				return function(){
       
    58 					console[type](Array.prototype.join.call(arguments, " "));
       
    59 				};
       
    60 			})();
       
    61 		}
       
    62 		// clear the console on load. This is more than a convenience - too many logs crashes it.
       
    63 		// If closed it throws an error
       
    64 		try{ console.clear(); }catch(e){}
       
    65 	}
       
    66 
       
    67 	if(
       
    68 		has("ff") ||								// Firefox has Firebug
       
    69 		has("chrome") ||							// Chrome 3+ has a console
       
    70 		has("safari") ||							// Safari 4 has a console
       
    71 		isNewIE ||									// Has the new IE console
       
    72 		window.firebug ||							// Testing for mozilla firebug lite
       
    73 		(typeof console != "undefined" && console.firebug) || //The firebug console
       
    74 		dojo.config.useCustomLogger ||				// Allow custom loggers
       
    75 		has("air")									// isDebug triggers AIRInsector, not Firebug
       
    76 	){
       
    77 		return;
       
    78 	}
       
    79 
       
    80 	// don't build firebug in iframes
       
    81 	try{
       
    82 		if(window != window.parent){
       
    83 			// but if we've got a parent logger, connect to it
       
    84 			if(window.parent["console"]){
       
    85 				window.console = window.parent.console;
       
    86 			}
       
    87 			return;
       
    88 		}
       
    89 	}catch(e){/*squelch*/}
       
    90 
       
    91 	// ***************************************************************************
       
    92 	// Placing these variables before the functions that use them to avoid a
       
    93 	// shrinksafe bug where variable renaming does not happen correctly otherwise.
       
    94 
       
    95 	// most of the objects in this script are run anonomously
       
    96 	var _firebugDoc = document;
       
    97 	var _firebugWin = window;
       
    98 	var __consoleAnchorId__ = 0;
       
    99 
       
   100 	var consoleFrame = null;
       
   101 	var consoleBody = null;
       
   102 	var consoleObjectInspector = null;
       
   103 	var fireBugTabs = null;
       
   104 	var commandLine = null;
       
   105 	var consoleToolbar = null;
       
   106 
       
   107 	var frameVisible = false;
       
   108 	var messageQueue = [];
       
   109 	var groupStack = [];
       
   110 	var timeMap = {};
       
   111 	var countMap = {};
       
   112 
       
   113 	var consoleDomInspector = null;
       
   114 	var _inspectionMoveConnection;
       
   115 	var _inspectionClickConnection;
       
   116 	var _inspectionEnabled = false;
       
   117 	var _inspectionTimer = null;
       
   118 	var _inspectTempNode = document.createElement("div");
       
   119 
       
   120 
       
   121 	var _inspectCurrentNode;
       
   122 	var _restoreBorderStyle;
       
   123 
       
   124 	// ***************************************************************************
       
   125 
       
   126 	window.console = {
       
   127 		_connects: [],
       
   128 		log: function(){
       
   129 			// summary:
       
   130 			//		Sends arguments to console.
       
   131 			logFormatted(arguments, "");
       
   132 		},
       
   133 
       
   134 		debug: function(){
       
   135 			// summary:
       
   136 			//		Sends arguments to console. Missing finctionality to show script line of trace.
       
   137 			logFormatted(arguments, "debug");
       
   138 		},
       
   139 
       
   140 		info: function(){
       
   141 			// summary:
       
   142 			//		Sends arguments to console, highlighted with (I) icon.
       
   143 			logFormatted(arguments, "info");
       
   144 		},
       
   145 
       
   146 		warn: function(){
       
   147 			// summary:
       
   148 			//		Sends warning arguments to console, highlighted with (!) icon and blue style.
       
   149 			logFormatted(arguments, "warning");
       
   150 		},
       
   151 
       
   152 		error: function(){
       
   153 			// summary:
       
   154 			//		Sends error arguments (object) to console, highlighted with (X) icon and yellow style
       
   155 			//		NEW: error object now displays in object inspector
       
   156 			logFormatted(arguments, "error");
       
   157 		},
       
   158 
       
   159 		assert: function(truth, message){
       
   160 			// summary:
       
   161 			//		Tests for true. Throws exception if false.
       
   162 			if(!truth){
       
   163 				var args = [];
       
   164 				for(var i = 1; i < arguments.length; ++i){
       
   165 					args.push(arguments[i]);
       
   166 				}
       
   167 
       
   168 				logFormatted(args.length ? args : ["Assertion Failure"], "error");
       
   169 				throw message ? message : "Assertion Failure";
       
   170 			}
       
   171 		},
       
   172 
       
   173 		dir: function(obj){
       
   174 			var str = printObject( obj );
       
   175 			str = str.replace(/\n/g, "<br />");
       
   176 			str = str.replace(/\t/g, "&nbsp;&nbsp;&nbsp;&nbsp;");
       
   177 			logRow([str], "dir");
       
   178 		},
       
   179 
       
   180 		dirxml: function(node){
       
   181 			var html = [];
       
   182 			appendNode(node, html);
       
   183 			logRow(html, "dirxml");
       
   184 		},
       
   185 
       
   186 		group: function(){
       
   187 			// summary:
       
   188 			//		collects log messages into a group, starting with this call and ending with
       
   189 			//		groupEnd(). Missing collapse functionality
       
   190 			logRow(arguments, "group", pushGroup);
       
   191 		},
       
   192 
       
   193 		groupEnd: function(){
       
   194 			// summary:
       
   195 			//		Closes group. See above
       
   196 			logRow(arguments, "", popGroup);
       
   197 		},
       
   198 
       
   199 		time: function(name){
       
   200 			// summary:
       
   201 			//		Starts timers assigned to name given in argument. Timer stops and displays on timeEnd(title);
       
   202 			// example:
       
   203 			//	|	console.time("load");
       
   204 			//	|	console.time("myFunction");
       
   205 			//	|	console.timeEnd("load");
       
   206 			//	|	console.timeEnd("myFunction");
       
   207 			timeMap[name] = new Date().getTime();
       
   208 		},
       
   209 
       
   210 		timeEnd: function(name){
       
   211 			// summary:
       
   212 			//		See above.
       
   213 			if(name in timeMap){
       
   214 				var delta = (new Date()).getTime() - timeMap[name];
       
   215 				logFormatted([name+ ":", delta+"ms"]);
       
   216 				delete timeMap[name];
       
   217 			}
       
   218 		},
       
   219 
       
   220 		count: function(name){
       
   221 			// summary:
       
   222 			//		Not supported
       
   223 			if(!countMap[name]) countMap[name] = 0;
       
   224 			countMap[name]++;
       
   225 			logFormatted([name+": "+countMap[name]]);
       
   226 		},
       
   227 
       
   228 		trace: function(_value){
       
   229 			var stackAmt = _value || 3;
       
   230 			var f = console.trace.caller; //function that called trace
       
   231 			console.log(">>> console.trace(stack)");
       
   232 			for(var i=0;i<stackAmt;i++){
       
   233 				var func = f.toString();
       
   234 				var args=[];
       
   235 				for (var a = 0; a < f.arguments.length; a++){
       
   236 					args.push(f.arguments[a]);
       
   237 				}
       
   238 				if(f.arguments.length){
       
   239 					console.dir({"function":func, "arguments":args});
       
   240 				}else{
       
   241 					console.dir({"function":func});
       
   242 				}
       
   243 
       
   244 				f = f.caller;
       
   245 			}
       
   246 		},
       
   247 
       
   248 		profile: function(){
       
   249 			// summary:
       
   250 			//		Not supported
       
   251 			this.warn(["profile() not supported."]);
       
   252 		},
       
   253 
       
   254 		profileEnd: function(){ },
       
   255 
       
   256 		clear: function(){
       
   257 			// summary:
       
   258 			//		Clears message console. Do not call this directly
       
   259 			if(consoleBody){
       
   260 				while(consoleBody.childNodes.length){
       
   261 					dojo.destroy(consoleBody.firstChild);
       
   262 				}
       
   263 			}
       
   264 			dojo.forEach(this._connects,dojo.disconnect);
       
   265 		},
       
   266 
       
   267 		open: function(){
       
   268 			// summary:
       
   269 			//		Opens message console. Do not call this directly
       
   270 			toggleConsole(true);
       
   271 		},
       
   272 
       
   273 		close: function(){
       
   274 			// summary:
       
   275 			//		Closes message console. Do not call this directly
       
   276 			if(frameVisible){
       
   277 				toggleConsole();
       
   278 			}
       
   279 		},
       
   280 		_restoreBorder: function(){
       
   281 			if(_inspectCurrentNode){
       
   282 				_inspectCurrentNode.style.border = _restoreBorderStyle;
       
   283 			}
       
   284 		},
       
   285 		openDomInspector: function(){
       
   286 			_inspectionEnabled = true;
       
   287 			consoleBody.style.display = "none";
       
   288 			consoleDomInspector.style.display = "block";
       
   289 			consoleObjectInspector.style.display = "none";
       
   290 			document.body.style.cursor = "pointer";
       
   291 			_inspectionMoveConnection = dojo.connect(document, "mousemove", function(evt){
       
   292 				if(!_inspectionEnabled){ return; }
       
   293 				if(!_inspectionTimer){
       
   294 					_inspectionTimer = setTimeout(function(){ _inspectionTimer = null; }, 50);
       
   295 				}else{
       
   296 					return;
       
   297 				}
       
   298 				var node = evt.target;
       
   299 				if(node && (_inspectCurrentNode !== node)){
       
   300 					var parent = true;
       
   301 
       
   302 					console._restoreBorder();
       
   303 					var html = [];
       
   304 					appendNode(node, html);
       
   305 					consoleDomInspector.innerHTML = html.join("");
       
   306 
       
   307 					_inspectCurrentNode = node;
       
   308 					_restoreBorderStyle = _inspectCurrentNode.style.border;
       
   309 					_inspectCurrentNode.style.border = "#0000FF 1px solid";
       
   310 				}
       
   311 			});
       
   312 			setTimeout(function(){
       
   313 				_inspectionClickConnection = dojo.connect(document, "click", function(evt){
       
   314 					document.body.style.cursor = "";
       
   315 					_inspectionEnabled = !_inspectionEnabled;
       
   316 					dojo.disconnect(_inspectionClickConnection);
       
   317 					// console._restoreBorder();
       
   318 				});
       
   319 			}, 30);
       
   320 		},
       
   321 		_closeDomInspector: function(){
       
   322 			document.body.style.cursor = "";
       
   323 			dojo.disconnect(_inspectionMoveConnection);
       
   324 			dojo.disconnect(_inspectionClickConnection);
       
   325 			_inspectionEnabled = false;
       
   326 			console._restoreBorder();
       
   327 		},
       
   328 		openConsole:function(){
       
   329 			// summary:
       
   330 			//		Closes object inspector and opens message console. Do not call this directly
       
   331 			consoleBody.style.display = "block";
       
   332 			consoleDomInspector.style.display = "none";
       
   333 			consoleObjectInspector.style.display = "none";
       
   334 			console._closeDomInspector();
       
   335 		},
       
   336 		openObjectInspector:function(){
       
   337 			consoleBody.style.display = "none";
       
   338 			consoleDomInspector.style.display = "none";
       
   339 			consoleObjectInspector.style.display = "block";
       
   340 			console._closeDomInspector();
       
   341 		},
       
   342 		recss: function(){
       
   343 			// this is placed in dojo since the console is most likely
       
   344 			// in another window and dojo is easilly accessible
       
   345 			var i,a,s;a=document.getElementsByTagName('link');
       
   346 			for(i=0;i<a.length;i++){
       
   347 				s=a[i];
       
   348 				if(s.rel.toLowerCase().indexOf('stylesheet')>=0&&s.href){
       
   349 					var h=s.href.replace(/(&|%5C?)forceReload=\d+/,'');
       
   350 					s.href=h+(h.indexOf('?')>=0?'&':'?')+'forceReload='+new Date().valueOf();
       
   351 				}
       
   352 			}
       
   353 		}
       
   354 	};
       
   355 
       
   356 	// ***************************************************************************
       
   357 
       
   358 	function toggleConsole(forceOpen){
       
   359 		frameVisible = forceOpen || !frameVisible;
       
   360 		if(consoleFrame){
       
   361 			consoleFrame.style.display = frameVisible ? "block" : "none";
       
   362 		}
       
   363 	}
       
   364 
       
   365 	function focusCommandLine(){
       
   366 		toggleConsole(true);
       
   367 		if(commandLine){
       
   368 			commandLine.focus();
       
   369 		}
       
   370 	}
       
   371 
       
   372 	function openWin(x,y,w,h){
       
   373 		var win = window.open("","_firebug","status=0,menubar=0,resizable=1,top="+y+",left="+x+",width="+w+",height="+h+",scrollbars=1,addressbar=0");
       
   374 		if(!win){
       
   375 			var msg = "Firebug Lite could not open a pop-up window, most likely because of a blocker.\n" +
       
   376 				"Either enable pop-ups for this domain, or change the djConfig to popup=false.";
       
   377 			alert(msg);
       
   378 		}
       
   379 		createResizeHandler(win);
       
   380 		var newDoc=win.document;
       
   381 		//Safari needs an HTML height
       
   382 		var HTMLstring=	'<html style="height:100%;"><head><title>Firebug Lite</title></head>\n' +
       
   383 					'<body bgColor="#ccc" style="height:97%;" onresize="opener.onFirebugResize()">\n' +
       
   384 					'<div id="fb"></div>' +
       
   385 					'</body></html>';
       
   386 
       
   387 		newDoc.write(HTMLstring);
       
   388 		newDoc.close();
       
   389 		return win;
       
   390 	}
       
   391 
       
   392 	function createResizeHandler(wn){
       
   393 		// summary:
       
   394 		//		Creates handle for onresize window. Called from script in popup's body tag (so that it will work with IE).
       
   395 		//
       
   396 
       
   397 		var d = new Date();
       
   398 			d.setTime(d.getTime()+(60*24*60*60*1000)); // 60 days
       
   399 			d = d.toUTCString();
       
   400 
       
   401 			var dc = wn.document,
       
   402 				getViewport;
       
   403 
       
   404 			if (wn.innerWidth){
       
   405 				getViewport = function(){
       
   406 					return{w:wn.innerWidth, h:wn.innerHeight};
       
   407 				};
       
   408 			}else if (dc.documentElement && dc.documentElement.clientWidth){
       
   409 				getViewport = function(){
       
   410 					return{w:dc.documentElement.clientWidth, h:dc.documentElement.clientHeight};
       
   411 				};
       
   412 			}else if (dc.body){
       
   413 				getViewport = function(){
       
   414 					return{w:dc.body.clientWidth, h:dc.body.clientHeight};
       
   415 				};
       
   416 			}
       
   417 
       
   418 
       
   419 		window.onFirebugResize = function(){
       
   420 
       
   421 			//resize the height of the console log body
       
   422 			layout(getViewport().h);
       
   423 
       
   424 			clearInterval(wn._firebugWin_resize);
       
   425 			wn._firebugWin_resize = setTimeout(function(){
       
   426 				var x = wn.screenLeft,
       
   427 					y = wn.screenTop,
       
   428 					w = wn.outerWidth  || wn.document.body.offsetWidth,
       
   429 					h = wn.outerHeight || wn.document.body.offsetHeight;
       
   430 
       
   431 				document.cookie = "_firebugPosition=" + [x,y,w,h].join(",") + "; expires="+d+"; path=/";
       
   432 
       
   433 			 }, 5000); //can't capture window.onMove - long timeout gives better chance of capturing a resize, then the move
       
   434 
       
   435 		};
       
   436 	}
       
   437 
       
   438 
       
   439 	/*****************************************************************************/
       
   440 
       
   441 
       
   442 	function createFrame(){
       
   443 		if(consoleFrame){
       
   444 			return;
       
   445 		}
       
   446 		toggleConsole(true);
       
   447 		if(dojo.config.popup){
       
   448 			var containerHeight = "100%";
       
   449 			var cookieMatch = document.cookie.match(/(?:^|; )_firebugPosition=([^;]*)/);
       
   450 			var p = cookieMatch ? cookieMatch[1].split(",") : [2,2,320,480];
       
   451 
       
   452 			_firebugWin = openWin(p[0],p[1],p[2],p[3]);	// global
       
   453 			_firebugDoc = _firebugWin.document;			// global
       
   454 
       
   455 			dojo.config.debugContainerId = 'fb';
       
   456 
       
   457 			// connecting popup
       
   458 			_firebugWin.console = window.console;
       
   459 			_firebugWin.dojo = window.dojo;
       
   460 		}else{
       
   461 			_firebugDoc = document;
       
   462 			containerHeight = (dojo.config.debugHeight || 300) + "px";
       
   463 		}
       
   464 
       
   465 		var styleElement = _firebugDoc.createElement("link");
       
   466 		styleElement.href = require.toUrl("./firebug.css");
       
   467 		styleElement.rel = "stylesheet";
       
   468 		styleElement.type = "text/css";
       
   469 		var styleParent = _firebugDoc.getElementsByTagName("head");
       
   470 		if(styleParent){
       
   471 			styleParent = styleParent[0];
       
   472 		}
       
   473 		if(!styleParent){
       
   474 			styleParent = _firebugDoc.getElementsByTagName("html")[0];
       
   475 		}
       
   476 		if(has("ie")){
       
   477 			window.setTimeout(function(){ styleParent.appendChild(styleElement); }, 0);
       
   478 		}else{
       
   479 			styleParent.appendChild(styleElement);
       
   480 		}
       
   481 
       
   482 		if(dojo.config.debugContainerId){
       
   483 			consoleFrame = _firebugDoc.getElementById(dojo.config.debugContainerId);
       
   484 		}
       
   485 		if(!consoleFrame){
       
   486 			consoleFrame = _firebugDoc.createElement("div");
       
   487 			_firebugDoc.body.appendChild(consoleFrame);
       
   488 		}
       
   489 		consoleFrame.className += " firebug";
       
   490 		consoleFrame.id = "firebug";
       
   491 		consoleFrame.style.height = containerHeight;
       
   492 		consoleFrame.style.display = (frameVisible ? "block" : "none");
       
   493 
       
   494 		var buildLink = function(label, title, method, _class){
       
   495 			return '<li class="'+_class+'"><a href="javascript:void(0);" onclick="console.'+ method +'(); return false;" title="'+title+'">'+label+'</a></li>';
       
   496 		};
       
   497 		consoleFrame.innerHTML =
       
   498 			  '<div id="firebugToolbar">'
       
   499 			+ '  <ul id="fireBugTabs" class="tabs">'
       
   500 
       
   501 			+ buildLink("Clear", "Remove All Console Logs", "clear", "")
       
   502 			+ buildLink("ReCSS", "Refresh CSS without reloading page", "recss", "")
       
   503 
       
   504 			+ buildLink("Console", "Show Console Logs", "openConsole", "gap")
       
   505 			+ buildLink("DOM", "Show DOM Inspector", "openDomInspector", "")
       
   506 			+ buildLink("Object", "Show Object Inspector", "openObjectInspector", "")
       
   507 			+ ((dojo.config.popup) ? "" : buildLink("Close", "Close the console", "close", "gap"))
       
   508 
       
   509 			+ '	</ul>'
       
   510 			+ '</div>'
       
   511 			+ '<input type="text" id="firebugCommandLine" />'
       
   512 			+ '<div id="firebugLog"></div>'
       
   513 			+ '<div id="objectLog" style="display:none;">Click on an object in the Log display</div>'
       
   514 			+ '<div id="domInspect" style="display:none;">Hover over HTML elements in the main page. Click to hold selection.</div>';
       
   515 
       
   516 
       
   517 		consoleToolbar = _firebugDoc.getElementById("firebugToolbar");
       
   518 
       
   519 		commandLine = _firebugDoc.getElementById("firebugCommandLine");
       
   520 		addEvent(commandLine, "keydown", onCommandLineKeyDown);
       
   521 
       
   522 		addEvent(_firebugDoc, has("ie") || has("safari") ? "keydown" : "keypress", onKeyDown);
       
   523 
       
   524 		consoleBody = _firebugDoc.getElementById("firebugLog");
       
   525 		consoleObjectInspector = _firebugDoc.getElementById("objectLog");
       
   526 		consoleDomInspector = _firebugDoc.getElementById("domInspect");
       
   527 		fireBugTabs = _firebugDoc.getElementById("fireBugTabs");
       
   528 		layout();
       
   529 		flush();
       
   530 	}
       
   531 
       
   532 	dojo.addOnLoad(createFrame);
       
   533 
       
   534 	function clearFrame(){
       
   535 		_firebugDoc = null;
       
   536 
       
   537 		if(_firebugWin.console){
       
   538 			_firebugWin.console.clear();
       
   539 		}
       
   540 		_firebugWin = null;
       
   541 		consoleFrame = null;
       
   542 		consoleBody = null;
       
   543 		consoleObjectInspector = null;
       
   544 		consoleDomInspector = null;
       
   545 		commandLine = null;
       
   546 		messageQueue = [];
       
   547 		groupStack = [];
       
   548 		timeMap = {};
       
   549 	}
       
   550 
       
   551 
       
   552 	function evalCommandLine(){
       
   553 		var text = commandLine.value;
       
   554 		commandLine.value = "";
       
   555 
       
   556 		logRow([">  ", text], "command");
       
   557 
       
   558 		var value;
       
   559 		try{
       
   560 			value = eval(text);
       
   561 		}catch(e){
       
   562 			console.debug(e); // put exception on the console
       
   563 		}
       
   564 
       
   565 		console.log(value);
       
   566 	}
       
   567 
       
   568 	function layout(h){
       
   569 		var tHeight = 25; //consoleToolbar.offsetHeight; // tab style not ready on load - throws off layout
       
   570 		var height = h ?
       
   571 			h  - (tHeight + commandLine.offsetHeight +25 + (h*.01)) + "px" :
       
   572 			(consoleFrame.offsetHeight - tHeight - commandLine.offsetHeight) + "px";
       
   573 
       
   574 		consoleBody.style.top = tHeight + "px";
       
   575 		consoleBody.style.height = height;
       
   576 		consoleObjectInspector.style.height = height;
       
   577 		consoleObjectInspector.style.top = tHeight + "px";
       
   578 		consoleDomInspector.style.height = height;
       
   579 		consoleDomInspector.style.top = tHeight + "px";
       
   580 		commandLine.style.bottom = 0;
       
   581 
       
   582 		dojo.addOnWindowUnload(clearFrame);
       
   583 	}
       
   584 
       
   585 	function logRow(message, className, handler){
       
   586 		if(consoleBody){
       
   587 			writeMessage(message, className, handler);
       
   588 		}else{
       
   589 			messageQueue.push([message, className, handler]);
       
   590 		}
       
   591 	}
       
   592 
       
   593 	function flush(){
       
   594 		var queue = messageQueue;
       
   595 		messageQueue = [];
       
   596 
       
   597 		for(var i = 0; i < queue.length; ++i){
       
   598 			writeMessage(queue[i][0], queue[i][1], queue[i][2]);
       
   599 		}
       
   600 	}
       
   601 
       
   602 	function writeMessage(message, className, handler){
       
   603 		var isScrolledToBottom =
       
   604 			consoleBody.scrollTop + consoleBody.offsetHeight >= consoleBody.scrollHeight;
       
   605 
       
   606 		handler = handler||writeRow;
       
   607 
       
   608 		handler(message, className);
       
   609 
       
   610 		if(isScrolledToBottom){
       
   611 			consoleBody.scrollTop = consoleBody.scrollHeight - consoleBody.offsetHeight;
       
   612 		}
       
   613 	}
       
   614 
       
   615 	function appendRow(row){
       
   616 		var container = groupStack.length ? groupStack[groupStack.length-1] : consoleBody;
       
   617 		container.appendChild(row);
       
   618 	}
       
   619 
       
   620 	function writeRow(message, className){
       
   621 		var row = consoleBody.ownerDocument.createElement("div");
       
   622 		row.className = "logRow" + (className ? " logRow-"+className : "");
       
   623 		row.innerHTML = message.join("");
       
   624 		appendRow(row);
       
   625 	}
       
   626 
       
   627 	function pushGroup(message, className){
       
   628 		logFormatted(message, className);
       
   629 
       
   630 		//var groupRow = consoleBody.ownerDocument.createElement("div");
       
   631 		//groupRow.className = "logGroup";
       
   632 		var groupRowBox = consoleBody.ownerDocument.createElement("div");
       
   633 		groupRowBox.className = "logGroupBox";
       
   634 		//groupRow.appendChild(groupRowBox);
       
   635 		appendRow(groupRowBox);
       
   636 		groupStack.push(groupRowBox);
       
   637 	}
       
   638 
       
   639 	function popGroup(){
       
   640 		groupStack.pop();
       
   641 	}
       
   642 
       
   643 	// ***************************************************************************
       
   644 
       
   645 	function logFormatted(objects, className){
       
   646 		var html = [];
       
   647 
       
   648 		var format = objects[0];
       
   649 		var objIndex = 0;
       
   650 
       
   651 		if(typeof(format) != "string"){
       
   652 			format = "";
       
   653 			objIndex = -1;
       
   654 		}
       
   655 
       
   656 		var parts = parseFormat(format);
       
   657 
       
   658 		for(var i = 0; i < parts.length; ++i){
       
   659 			var part = parts[i];
       
   660 			if(part && typeof part == "object"){
       
   661 				part.appender(objects[++objIndex], html);
       
   662 			}else{
       
   663 				appendText(part, html);
       
   664 			}
       
   665 		}
       
   666 
       
   667 
       
   668 		var ids = [];
       
   669 		var obs = [];
       
   670 		for(i = objIndex+1; i < objects.length; ++i){
       
   671 			appendText(" ", html);
       
   672 
       
   673 			var object = objects[i];
       
   674 			if(object === undefined || object === null ){
       
   675 				appendNull(object, html);
       
   676 
       
   677 			}else if(typeof(object) == "string"){
       
   678 				appendText(object, html);
       
   679 
       
   680 			}else if(object instanceof Date){
       
   681 				appendText(object.toString(), html);
       
   682 
       
   683 			}else if(object.nodeType == 9){
       
   684 				appendText("[ XmlDoc ]", html);
       
   685 
       
   686 			}else{
       
   687 				// Create link for object inspector
       
   688 				// need to create an ID for this link, since it is currently text
       
   689 				var id = "_a" + __consoleAnchorId__++;
       
   690 				ids.push(id);
       
   691 				// need to save the object, so the arrays line up
       
   692 				obs.push(object);
       
   693 				var str = '<a id="'+id+'" href="javascript:void(0);">'+getObjectAbbr(object)+'</a>';
       
   694 
       
   695 				appendLink( str , html);
       
   696 			}
       
   697 		}
       
   698 
       
   699 		logRow(html, className);
       
   700 
       
   701 		// Now that the row is inserted in the DOM, loop through all of the links that were just created
       
   702 		for(i=0; i<ids.length; i++){
       
   703 			var btn = _firebugDoc.getElementById(ids[i]);
       
   704 			if(!btn){ continue; }
       
   705 
       
   706 			// store the object in the dom btn for reference later
       
   707 			// avoid parsing these objects unless necessary
       
   708 			btn.obj = obs[i];
       
   709 
       
   710 			_firebugWin.console._connects.push(dojo.connect(btn, "onclick", function(){
       
   711 
       
   712 				console.openObjectInspector();
       
   713 
       
   714 				try{
       
   715 					printObject(this.obj);
       
   716 				}catch(e){
       
   717 					this.obj = e;
       
   718 				}
       
   719 				consoleObjectInspector.innerHTML = "<pre>" + printObject( this.obj ) + "</pre>";
       
   720 			}));
       
   721 		}
       
   722 	}
       
   723 
       
   724 	function parseFormat(format){
       
   725 		var parts = [];
       
   726 
       
   727 		var reg = /((^%|[^\\]%)(\d+)?(\.)([a-zA-Z]))|((^%|[^\\]%)([a-zA-Z]))/;
       
   728 		var appenderMap = {s: appendText, d: appendInteger, i: appendInteger, f: appendFloat};
       
   729 
       
   730 		for(var m = reg.exec(format); m; m = reg.exec(format)){
       
   731 			var type = m[8] ? m[8] : m[5];
       
   732 			var appender = type in appenderMap ? appenderMap[type] : appendObject;
       
   733 			var precision = m[3] ? parseInt(m[3]) : (m[4] == "." ? -1 : 0);
       
   734 
       
   735 			parts.push(format.substr(0, m[0][0] == "%" ? m.index : m.index+1));
       
   736 			parts.push({appender: appender, precision: precision});
       
   737 
       
   738 			format = format.substr(m.index+m[0].length);
       
   739 		}
       
   740 
       
   741 		parts.push(format);
       
   742 
       
   743 		return parts;
       
   744 	}
       
   745 
       
   746 	function escapeHTML(value){
       
   747 		function replaceChars(ch){
       
   748 			switch(ch){
       
   749 				case "<":
       
   750 					return "&lt;";
       
   751 				case ">":
       
   752 					return "&gt;";
       
   753 				case "&":
       
   754 					return "&amp;";
       
   755 				case "'":
       
   756 					return "&#39;";
       
   757 				case '"':
       
   758 					return "&quot;";
       
   759 			}
       
   760 			return "?";
       
   761 		}
       
   762 		return String(value).replace(/[<>&"']/g, replaceChars);
       
   763 	}
       
   764 
       
   765 	function objectToString(object){
       
   766 		try{
       
   767 			return object+"";
       
   768 		}catch(e){
       
   769 			return null;
       
   770 		}
       
   771 	}
       
   772 
       
   773 	// ***************************************************************************
       
   774 	function appendLink(object, html){
       
   775 		// needed for object links - no HTML escaping
       
   776 		html.push( objectToString(object) );
       
   777 	}
       
   778 
       
   779 	function appendText(object, html){
       
   780 		html.push(escapeHTML(objectToString(object)));
       
   781 	}
       
   782 
       
   783 	function appendNull(object, html){
       
   784 		html.push('<span class="objectBox-null">', escapeHTML(objectToString(object)), '</span>');
       
   785 	}
       
   786 
       
   787 	function appendString(object, html){
       
   788 		html.push('<span class="objectBox-string">&quot;', escapeHTML(objectToString(object)),
       
   789 			'&quot;</span>');
       
   790 	}
       
   791 
       
   792 	function appendInteger(object, html){
       
   793 		html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>');
       
   794 	}
       
   795 
       
   796 	function appendFloat(object, html){
       
   797 		html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>');
       
   798 	}
       
   799 
       
   800 	function appendFunction(object, html){
       
   801 		html.push('<span class="objectBox-function">', getObjectAbbr(object), '</span>');
       
   802 	}
       
   803 
       
   804 	function appendObject(object, html){
       
   805 		try{
       
   806 			if(object === undefined){
       
   807 				appendNull("undefined", html);
       
   808 			}else if(object === null){
       
   809 				appendNull("null", html);
       
   810 			}else if(typeof object == "string"){
       
   811 				appendString(object, html);
       
   812 			}else if(typeof object == "number"){
       
   813 				appendInteger(object, html);
       
   814 			}else if(typeof object == "function"){
       
   815 				appendFunction(object, html);
       
   816 			}else if(object.nodeType == 1){
       
   817 				appendSelector(object, html);
       
   818 			}else if(typeof object == "object"){
       
   819 				appendObjectFormatted(object, html);
       
   820 			}else{
       
   821 				appendText(object, html);
       
   822 			}
       
   823 		}catch(e){
       
   824 			/* squelch */
       
   825 		}
       
   826 	}
       
   827 
       
   828 	function appendObjectFormatted(object, html){
       
   829 		var text = objectToString(object);
       
   830 		var reObject = /\[object (.*?)\]/;
       
   831 
       
   832 		var m = reObject.exec(text);
       
   833 		html.push('<span class="objectBox-object">', m ? m[1] : text, '</span>');
       
   834 	}
       
   835 
       
   836 	function appendSelector(object, html){
       
   837 		html.push('<span class="objectBox-selector">');
       
   838 
       
   839 		html.push('<span class="selectorTag">', escapeHTML(object.nodeName.toLowerCase()), '</span>');
       
   840 		if(object.id){
       
   841 			html.push('<span class="selectorId">#', escapeHTML(object.id), '</span>');
       
   842 		}
       
   843 		if(object.className){
       
   844 			html.push('<span class="selectorClass">.', escapeHTML(object.className), '</span>');
       
   845 		}
       
   846 
       
   847 		html.push('</span>');
       
   848 	}
       
   849 
       
   850 	function appendNode(node, html){
       
   851 		if(node.nodeType == 1){
       
   852 			html.push(
       
   853 				'<div class="objectBox-element">',
       
   854 					'&lt;<span class="nodeTag">', node.nodeName.toLowerCase(), '</span>');
       
   855 
       
   856 			for(var i = 0; i < node.attributes.length; ++i){
       
   857 				var attr = node.attributes[i];
       
   858 				if(!attr.specified){ continue; }
       
   859 
       
   860 				html.push('&nbsp;<span class="nodeName">', attr.nodeName.toLowerCase(),
       
   861 					'</span>=&quot;<span class="nodeValue">', escapeHTML(attr.nodeValue),
       
   862 					'</span>&quot;');
       
   863 			}
       
   864 
       
   865 			if(node.firstChild){
       
   866 				html.push('&gt;</div><div class="nodeChildren">');
       
   867 
       
   868 				for(var child = node.firstChild; child; child = child.nextSibling){
       
   869 					appendNode(child, html);
       
   870 				}
       
   871 
       
   872 				html.push('</div><div class="objectBox-element">&lt;/<span class="nodeTag">',
       
   873 					node.nodeName.toLowerCase(), '&gt;</span></div>');
       
   874 			}else{
       
   875 				html.push('/&gt;</div>');
       
   876 			}
       
   877 		}else if (node.nodeType == 3){
       
   878 			html.push('<div class="nodeText">', escapeHTML(node.nodeValue),
       
   879 				'</div>');
       
   880 		}
       
   881 	}
       
   882 
       
   883 	// ***************************************************************************
       
   884 
       
   885 	function addEvent(object, name, handler){
       
   886 		if(document.all){
       
   887 			object.attachEvent("on"+name, handler);
       
   888 		}else{
       
   889 			object.addEventListener(name, handler, false);
       
   890 		}
       
   891 	}
       
   892 
       
   893 	function removeEvent(object, name, handler){
       
   894 		if(document.all){
       
   895 			object.detachEvent("on"+name, handler);
       
   896 		}else{
       
   897 			object.removeEventListener(name, handler, false);
       
   898 		}
       
   899 	}
       
   900 
       
   901 	function cancelEvent(event){
       
   902 		if(document.all){
       
   903 			event.cancelBubble = true;
       
   904 		}else{
       
   905 			event.stopPropagation();
       
   906 		}
       
   907 	}
       
   908 
       
   909 	function onError(msg, href, lineNo){
       
   910 		var lastSlash = href.lastIndexOf("/");
       
   911 		var fileName = lastSlash == -1 ? href : href.substr(lastSlash+1);
       
   912 
       
   913 		var html = [
       
   914 			'<span class="errorMessage">', msg, '</span>',
       
   915 			'<div class="objectBox-sourceLink">', fileName, ' (line ', lineNo, ')</div>'
       
   916 		];
       
   917 
       
   918 		logRow(html, "error");
       
   919 	}
       
   920 
       
   921 
       
   922 	//After converting to div instead of iframe, now getting two keydowns right away in IE 6.
       
   923 	//Make sure there is a little bit of delay.
       
   924 	var onKeyDownTime = new Date().getTime();
       
   925 
       
   926 	function onKeyDown(event){
       
   927 		var timestamp = (new Date()).getTime();
       
   928 		if(timestamp > onKeyDownTime + 200){
       
   929 			event = dojo.fixEvent(event);
       
   930 			var keys = dojo.keys;
       
   931 			var ekc = event.keyCode;
       
   932 			onKeyDownTime = timestamp;
       
   933 			if(ekc == keys.F12){
       
   934 				toggleConsole();
       
   935 			}else if(
       
   936 				(ekc == keys.NUMPAD_ENTER || ekc == 76) &&
       
   937 				event.shiftKey &&
       
   938 				(event.metaKey || event.ctrlKey)
       
   939 			){
       
   940 				focusCommandLine();
       
   941 			}else{
       
   942 				return;
       
   943 			}
       
   944 			cancelEvent(event);
       
   945 		}
       
   946 	}
       
   947 
       
   948 	function onCommandLineKeyDown(e){
       
   949 		var dk = dojo.keys;
       
   950 		if(e.keyCode == 13 && commandLine.value){
       
   951 			addToHistory(commandLine.value);
       
   952 			evalCommandLine();
       
   953 		}else if(e.keyCode == 27){
       
   954 			commandLine.value = "";
       
   955 		}else if(e.keyCode == dk.UP_ARROW || e.charCode == dk.UP_ARROW){
       
   956 			navigateHistory("older");
       
   957 		}else if(e.keyCode == dk.DOWN_ARROW || e.charCode == dk.DOWN_ARROW){
       
   958 			navigateHistory("newer");
       
   959 		}else if(e.keyCode == dk.HOME || e.charCode == dk.HOME){
       
   960 			historyPosition = 1;
       
   961 			navigateHistory("older");
       
   962 		}else if(e.keyCode == dk.END || e.charCode == dk.END){
       
   963 			historyPosition = 999999;
       
   964 			navigateHistory("newer");
       
   965 		}
       
   966 	}
       
   967 
       
   968 	var historyPosition = -1;
       
   969 	var historyCommandLine = null;
       
   970 
       
   971 	function addToHistory(value){
       
   972 		var history = cookie("firebug_history");
       
   973 		history = (history) ? dojo.fromJson(history) : [];
       
   974 		var pos = dojo.indexOf(history, value);
       
   975 		if (pos != -1){
       
   976 			history.splice(pos, 1);
       
   977 		}
       
   978 		history.push(value);
       
   979 		cookie("firebug_history", dojo.toJson(history), 30);
       
   980 		while(history.length && !cookie("firebug_history")){
       
   981 			history.shift();
       
   982 			cookie("firebug_history", dojo.toJson(history), 30);
       
   983 		}
       
   984 		historyCommandLine = null;
       
   985 		historyPosition = -1;
       
   986 	}
       
   987 
       
   988 	function navigateHistory(direction){
       
   989 		var history = cookie("firebug_history");
       
   990 		history = (history) ? dojo.fromJson(history) : [];
       
   991 		if(!history.length){
       
   992 			return;
       
   993 		}
       
   994 
       
   995 		if(historyCommandLine === null){
       
   996 			historyCommandLine = commandLine.value;
       
   997 		}
       
   998 
       
   999 		if(historyPosition == -1){
       
  1000 			historyPosition = history.length;
       
  1001 		}
       
  1002 
       
  1003 		if(direction == "older"){
       
  1004 			--historyPosition;
       
  1005 			if(historyPosition < 0){
       
  1006 				historyPosition = 0;
       
  1007 			}
       
  1008 		}else if(direction == "newer"){
       
  1009 			++historyPosition;
       
  1010 			if(historyPosition > history.length){
       
  1011 				historyPosition = history.length;
       
  1012 			}
       
  1013 		}
       
  1014 
       
  1015 		if(historyPosition == history.length){
       
  1016 			commandLine.value = historyCommandLine;
       
  1017 			historyCommandLine = null;
       
  1018 		}else{
       
  1019 			commandLine.value = history[historyPosition];
       
  1020 		}
       
  1021 	}
       
  1022 
       
  1023 	function cookie(name, value){
       
  1024 		var c = document.cookie;
       
  1025 		if(arguments.length == 1){
       
  1026 			var matches = c.match(new RegExp("(?:^|; )" + name + "=([^;]*)"));
       
  1027 			return matches ? decodeURIComponent(matches[1]) : undefined; // String or undefined
       
  1028 		}else{
       
  1029 			var d = new Date();
       
  1030 			d.setMonth(d.getMonth()+1);
       
  1031 			document.cookie = name + "=" + encodeURIComponent(value) + ((d.toUtcString) ? "; expires=" + d.toUTCString() : "");
       
  1032 		}
       
  1033 	}
       
  1034 
       
  1035 	function isArray(it){
       
  1036 		return it && it instanceof Array || typeof it == "array";
       
  1037 	}
       
  1038 
       
  1039 	//***************************************************************************************************
       
  1040 	// Print Object Helpers
       
  1041 	function objectLength(o){
       
  1042 		var cnt = 0;
       
  1043 		for(var nm in o){
       
  1044 			cnt++;
       
  1045 		}
       
  1046 		return cnt;
       
  1047 	}
       
  1048 
       
  1049 	function printObject(o, i, txt, used){
       
  1050 		// Recursively trace object, indenting to represent depth for display in object inspector
       
  1051 		var ind = " \t";
       
  1052 		txt = txt || "";
       
  1053 		i = i || ind;
       
  1054 		used = used || [];
       
  1055 		var opnCls;
       
  1056 
       
  1057 		if(o && o.nodeType == 1){
       
  1058 			var html = [];
       
  1059 			appendNode(o, html);
       
  1060 			return html.join("");
       
  1061 		}
       
  1062 
       
  1063 		var br=",\n", cnt = 0, length = objectLength(o);
       
  1064 
       
  1065 		if(o instanceof Date){
       
  1066 			return i + o.toString() + br;
       
  1067 		}
       
  1068 		looking:
       
  1069 		for(var nm in o){
       
  1070 			cnt++;
       
  1071 			if(cnt==length){br = "\n";}
       
  1072 			if(o[nm] === window || o[nm] === document){
       
  1073 				// do nothing
       
  1074 			}else if(o[nm] === null){
       
  1075 				txt += i+nm + " : NULL" + br;
       
  1076 			}else if(o[nm] && o[nm].nodeType){
       
  1077 				if(o[nm].nodeType == 1){
       
  1078 					//txt += i+nm + " : < "+o[nm].tagName+" id=\""+ o[nm].id+"\" />" + br;
       
  1079 				}else if(o[nm].nodeType == 3){
       
  1080 					txt += i+nm + " : [ TextNode "+o[nm].data + " ]" + br;
       
  1081 				}
       
  1082 
       
  1083 			}else if(typeof o[nm] == "object" && (o[nm] instanceof String || o[nm] instanceof Number || o[nm] instanceof Boolean)){
       
  1084 				txt += i+nm + " : " + o[nm] + "," + br;
       
  1085 
       
  1086 			}else if(o[nm] instanceof Date){
       
  1087 				txt += i+nm + " : " + o[nm].toString() + br;
       
  1088 
       
  1089 			}else if(typeof(o[nm]) == "object" && o[nm]){
       
  1090 				for(var j = 0, seen; seen = used[j]; j++){
       
  1091 					if(o[nm] === seen){
       
  1092 						txt += i+nm + " : RECURSION" + br;
       
  1093 						continue looking;
       
  1094 					}
       
  1095 				}
       
  1096 				used.push(o[nm]);
       
  1097 
       
  1098 				opnCls = (isArray(o[nm]))?["[","]"]:["{","}"];
       
  1099 				txt += i+nm +" : " + opnCls[0] + "\n";//non-standard break, (no comma)
       
  1100 				txt += printObject(o[nm], i+ind, "", used);
       
  1101 				txt += i + opnCls[1] + br;
       
  1102 
       
  1103 			}else if(typeof o[nm] == "undefined"){
       
  1104 				txt += i+nm + " : undefined" + br;
       
  1105 			}else if(nm == "toString" && typeof o[nm] == "function"){
       
  1106 				var toString = o[nm]();
       
  1107 				if(typeof toString == "string" && toString.match(/function ?(.*?)\(/)){
       
  1108 					toString = escapeHTML(getObjectAbbr(o[nm]));
       
  1109 				}
       
  1110 				txt += i+nm +" : " + toString + br;
       
  1111 			}else{
       
  1112 				txt += i+nm +" : "+ escapeHTML(getObjectAbbr(o[nm])) + br;
       
  1113 			}
       
  1114 		}
       
  1115 		return txt;
       
  1116 	}
       
  1117 
       
  1118 	function getObjectAbbr(obj){
       
  1119 		// Gets an abbreviation of an object for display in log
       
  1120 		// X items in object, including id
       
  1121 		// X items in an array
       
  1122 		// TODO: Firebug Sr. actually goes by char count
       
  1123 		var isError = (obj instanceof Error);
       
  1124 		if(obj.nodeType == 1){
       
  1125 			return escapeHTML('< '+obj.tagName.toLowerCase()+' id=\"'+ obj.id+ '\" />');
       
  1126 		}
       
  1127 		if(obj.nodeType == 3){
       
  1128 			return escapeHTML('[TextNode: "'+obj.nodeValue+'"]');
       
  1129 		}
       
  1130 		var nm = (obj && (obj.id || obj.name || obj.ObjectID || obj.widgetId));
       
  1131 		if(!isError && nm){ return "{"+nm+"}";	}
       
  1132 
       
  1133 		var obCnt = 2;
       
  1134 		var arCnt = 4;
       
  1135 		var cnt = 0;
       
  1136 
       
  1137 		if(isError){
       
  1138 			nm = "[ Error: "+(obj.message || obj.description || obj)+" ]";
       
  1139 		}else if(isArray(obj)){
       
  1140 			nm = "[" + obj.slice(0,arCnt).join(",");
       
  1141 			if(obj.length > arCnt){
       
  1142 				nm += " ... ("+obj.length+" items)";
       
  1143 			}
       
  1144 			nm += "]";
       
  1145 		}else if(typeof obj == "function"){
       
  1146 			nm = obj + "";
       
  1147 			var reg = /function\s*([^\(]*)(\([^\)]*\))[^\{]*\{/;
       
  1148 			var m = reg.exec(nm);
       
  1149 			if(m){
       
  1150 				if(!m[1]){
       
  1151 					m[1] = "function";
       
  1152 				}
       
  1153 				nm = m[1] + m[2];
       
  1154 			}else{
       
  1155 				nm = "function()";
       
  1156 			}
       
  1157 		}else if(typeof obj != "object" || typeof obj == "string"){
       
  1158 			nm = obj + "";
       
  1159 		}else{
       
  1160 			nm = "{";
       
  1161 			for(var i in obj){
       
  1162 				cnt++;
       
  1163 				if(cnt > obCnt){ break; }
       
  1164 				nm += i+":"+escapeHTML(obj[i])+"  ";
       
  1165 			}
       
  1166 			nm+="}";
       
  1167 		}
       
  1168 
       
  1169 		return nm;
       
  1170 	}
       
  1171 
       
  1172 	//*************************************************************************************
       
  1173 
       
  1174 	//window.onerror = onError;
       
  1175 
       
  1176 	addEvent(document, has("ie") || has("safari") ? "keydown" : "keypress", onKeyDown);
       
  1177 
       
  1178 	if(	(document.documentElement.getAttribute("debug") == "true")||
       
  1179 		(dojo.config.isDebug)
       
  1180 	){
       
  1181 		toggleConsole(true);
       
  1182 	}
       
  1183 
       
  1184 	dojo.addOnWindowUnload(function(){
       
  1185 		// Erase the globals and event handlers I created, to prevent spurious leak warnings
       
  1186 		removeEvent(document, has("ie") || has("safari") ? "keydown" : "keypress", onKeyDown);
       
  1187 		window.onFirebugResize = null;
       
  1188 		window.console = null;
       
  1189 	});
       
  1190 
       
  1191 });