Subversion-Projekte lars-tiefland.prado

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
/*
2
 
3
Created By: Corey Johnson
4
E-mail: probablyCorey@gmail.com
5
 
6
Requires: Prototype Javascript library (http://prototype.conio.net/)
7
 
8
Use it all you want. Just remember to give me some credit :)
9
 
10
*/
11
 
12
// ------------
13
// Custom Event
14
// ------------
15
 
16
CustomEvent = Class.create();
17
CustomEvent.prototype = {
18
  initialize : function() {
19
  	this.listeners = []
20
  },
21
 
22
	addListener : function(method) {
23
		this.listeners.push(method)
24
	},
25
 
26
	removeListener : function(method) {
27
		var foundIndexes = this._findListenerIndexes(method)
28
 
29
		for(var i = 0; i < foundIndexes.length; i++) {
30
			this.listeners.splice(foundIndexes[i], 1)
31
		}
32
	},
33
 
34
	dispatch : function(handler) {
35
		for(var i = 0; i < this.listeners.length; i++) {
36
			try {
37
				this.listeners[i](handler)
38
			}
39
			catch (e) {
40
				alert("Could not run the listener " + this.listeners[i] + ". " + e)
41
			}
42
		}
43
	},
44
 
45
	// Private Methods
46
	// ---------------
47
	_findListenerIndexes : function(method) {
48
		var indexes = []
49
		for(var i = 0; i < this.listeners.length; i++) {
50
			if (this.listeners[i] == method) {
51
				indexes.push(i)
52
			}
53
		}
54
 
55
		return indexes
56
	}
57
};
58
 
59
// ------
60
// Cookie
61
// ------
62
 
63
var Cookie = {
64
	set : function(name, value, expirationInDays, path) {
65
		var cookie = escape(name) + "=" + escape(value)
66
 
67
		if (expirationInDays) {
68
			var date = new Date()
69
			date.setDate(date.getDate() + expirationInDays)
70
			cookie += "; expires=" + date.toGMTString()
71
		}
72
 
73
		if (path) {
74
			cookie += ";path=" + path
75
		}
76
 
77
		document.cookie = cookie
78
 
79
		if (value && (expirationInDays == undefined || expirationInDays > 0) && !this.get(name)) {
80
			Logger.error("Cookie (" + name + ") was not set correctly... The value was " + value.toString().length + " charachters long (This may be over the cookie limit)");
81
		}
82
	},
83
 
84
	get : function(name) {
85
		var pattern = "(^|;)\\s*" + escape(name) + "=([^;]+)"
86
 
87
		var m = document.cookie.match(pattern)
88
		if (m && m[2]) {
89
			return unescape(m[2])
90
		}
91
		else return null
92
	},
93
 
94
	getAll : function() {
95
		var cookies = document.cookie.split(';')
96
		var cookieArray = []
97
 
98
		for (var i = 0; i < cookies.length; i++) {
99
			try {
100
				var name = unescape(cookies[i].match(/^\s*([^=]+)/m)[1])
101
				var value = unescape(cookies[i].match(/=(.*$)/m)[1])
102
			}
103
			catch (e) {
104
				continue
105
			}
106
 
107
			cookieArray.push({name : name, value : value})
108
 
109
			if (cookieArray[name] != undefined) {
110
				Logger.waring("Trying to retrieve cookie named(" + name + "). There appears to be another property with this name though.");
111
			}
112
 
113
			cookieArray[name] = value
114
		}
115
 
116
		return cookieArray
117
	},
118
 
119
	clear : function(name) {
120
		this.set(name, "", -1)
121
	},
122
 
123
	clearAll : function() {
124
		var cookies = this.getAll()
125
 
126
		for(var i = 0; i < cookies.length; i++) {
127
			this.clear(cookies[i].name)
128
		}
129
 
130
	}
131
};
132
 
133
// ------
134
// Logger
135
// -----
136
 
137
Logger = {
138
	logEntries : [],
139
 
140
	onupdate : new CustomEvent(),
141
	onclear : new CustomEvent(),
142
 
143
 
144
	// Logger output
145
  log : function(message, tag) {
146
	  var logEntry = new LogEntry(message, tag || "info")
147
		this.logEntries.push(logEntry)
148
		this.onupdate.dispatch(logEntry)
149
	},
150
 
151
	info : function(message) {
152
		this.log(message, 'info')
153
		if(typeof(console) != "undefined")
154
			console.info(message);
155
	},
156
 
157
	debug : function(message) {
158
		this.log(message, 'debug')
159
		if(typeof(console) != "undefined")
160
			console.debug(message);
161
	},
162
 
163
	warn : function(message) {
164
	  this.log(message, 'warning')
165
		if(typeof(console) != "undefined")
166
			console.warn(message);
167
	},
168
 
169
	error : function(message, error) {
170
	  this.log(message + ": \n" + error, 'error')
171
		if(typeof(console) != "undefined")
172
			console.error(message + ": \n" + error);
173
 
174
	},
175
 
176
	clear : function () {
177
		this.logEntries = []
178
		this.onclear.dispatch()
179
	}
180
};
181
 
182
LogEntry = Class.create()
183
LogEntry.prototype = {
184
    initialize : function(message, tag) {
185
      this.message = message
186
      this.tag = tag
187
    }
188
};
189
 
190
LogConsole = Class.create();
191
LogConsole.prototype = {
192
 
193
  // Properties
194
  // ----------
195
  commandHistory : [],
196
  commandIndex : 0,
197
 
198
  hidden : true,
199
 
200
  // Methods
201
  // -------
202
 
203
  initialize : function(toggleKey) {
204
    this.outputCount = 0
205
    this.tagPattern = Cookie.get('tagPattern') || ".*"
206
 
207
  	// I hate writing javascript in HTML... but what's a better alternative
208
    this.logElement = document.createElement('div')
209
    document.body.appendChild(this.logElement)
210
    Element.hide(this.logElement)
211
 
212
	this.logElement.style.position = "absolute"
213
    this.logElement.style.left = '0px'
214
    this.logElement.style.width = '100%'
215
 
216
    this.logElement.style.textAlign = "left"
217
    this.logElement.style.fontFamily = "lucida console"
218
    this.logElement.style.fontSize = "100%"
219
    this.logElement.style.backgroundColor = 'darkgray'
220
    this.logElement.style.opacity = 0.9
221
    this.logElement.style.zIndex = 2000
222
 
223
    // Add toolbarElement
224
    this.toolbarElement = document.createElement('div')
225
    this.logElement.appendChild(this.toolbarElement)
226
    this.toolbarElement.style.padding = "0 0 0 2px"
227
 
228
    // Add buttons
229
    this.buttonsContainerElement = document.createElement('span')
230
    this.toolbarElement.appendChild(this.buttonsContainerElement)
231
 
232
	this.buttonsContainerElement.innerHTML += '<button onclick="logConsole.toggle()" style="float:right;color:black">close</button>'
233
    this.buttonsContainerElement.innerHTML += '<button onclick="Logger.clear()" style="float:right;color:black">clear</button>'
234
	if(!Prado.Inspector.disabled)
235
		this.buttonsContainerElement.innerHTML += '<button onclick="Prado.Inspector.inspect()" style="float:right;color:black; margin-right:15px;">Object Tree</button>'
236
 
237
 
238
		//Add Tag Filter
239
		this.tagFilterContainerElement = document.createElement('span')
240
    this.toolbarElement.appendChild(this.tagFilterContainerElement)
241
    this.tagFilterContainerElement.style.cssFloat = 'left'
242
    this.tagFilterContainerElement.appendChild(document.createTextNode("Log Filter"))
243
 
244
    this.tagFilterElement = document.createElement('input')
245
    this.tagFilterContainerElement.appendChild(this.tagFilterElement)
246
    this.tagFilterElement.style.width = '200px'
247
    this.tagFilterElement.value = this.tagPattern
248
    this.tagFilterElement.setAttribute('autocomplete', 'off') // So Firefox doesn't flip out
249
 
250
    Event.observe(this.tagFilterElement, 'keyup', this.updateTags.bind(this))
251
    Event.observe(this.tagFilterElement, 'click', function() {this.tagFilterElement.select()}.bind(this))
252
 
253
    // Add outputElement
254
    this.outputElement = document.createElement('div')
255
    this.logElement.appendChild(this.outputElement)
256
    this.outputElement.style.overflow = "auto"
257
    this.outputElement.style.clear = "both"
258
    this.outputElement.style.height = "200px"
259
    this.outputElement.style.backgroundColor = 'black'
260
 
261
    this.inputContainerElement = document.createElement('div')
262
    this.inputContainerElement.style.width = "100%"
263
    this.logElement.appendChild(this.inputContainerElement)
264
 
265
    this.inputElement = document.createElement('input')
266
    this.inputContainerElement.appendChild(this.inputElement)
267
    this.inputElement.style.width = '100%'
268
    this.inputElement.style.borderWidth = '0px' // Inputs with 100% width always seem to be too large (I HATE THEM) they only work if the border, margin and padding are 0
269
    this.inputElement.style.margin = '0px'
270
    this.inputElement.style.padding = '0px'
271
    this.inputElement.value = 'Type command here'
272
    this.inputElement.setAttribute('autocomplete', 'off') // So Firefox doesn't flip out
273
 
274
    Event.observe(this.inputElement, 'keyup', this.handleInput.bind(this))
275
    Event.observe(this.inputElement, 'click', function() {this.inputElement.select()}.bind(this))
276
 
277
	if(document.all && !window.opera)
278
	{
279
		window.setInterval(this.repositionWindow.bind(this), 500)
280
	}
281
	else
282
	{
283
		this.logElement.style.position="fixed";
284
		this.logElement.style.bottom="0px";
285
	}
286
	var self=this;
287
	Event.observe(document, 'keydown', function(e)
288
	{
289
		if((e.altKey==true) && Event.keyCode(e) == toggleKey ) //Alt+J | Ctrl+J
290
			self.toggle();
291
	});
292
 
293
    // Listen to the logger....
294
    Logger.onupdate.addListener(this.logUpdate.bind(this))
295
    Logger.onclear.addListener(this.clear.bind(this))
296
 
297
    // Preload log element with the log entries that have been entered
298
		for (var i = 0; i < Logger.logEntries.length; i++) {
299
  		this.logUpdate(Logger.logEntries[i])
300
  	}
301
 
302
  	// Feed all errors into the logger (For some unknown reason I can only get this to work
303
  	// with an inline event declaration)
304
  	Event.observe(window, 'error', function(msg, url, lineNumber) {Logger.error("Error in (" + (url || location) + ") on line "+lineNumber+"", msg)})
305
 
306
    // Allow acess key link
307
    var accessElement = document.createElement('span')
308
    accessElement.innerHTML = '<button style="position:absolute;top:-100px" onclick="javascript:logConsole.toggle()" accesskey="d"></button>'
309
  	document.body.appendChild(accessElement)
310
 
311
  	if (Cookie.get('ConsoleVisible') == 'true') {
312
		  this.toggle()
313
		}
314
	},
315
 
316
	toggle : function() {
317
	  if (this.logElement.style.display == 'none') {
318
		  this.show()
319
		}
320
		else {
321
			this.hide()
322
		}
323
	},
324
 
325
	show : function() {
326
	  Element.show(this.logElement)
327
	  this.outputElement.scrollTop = this.outputElement.scrollHeight // Scroll to bottom when toggled
328
	  if(document.all && !window.opera)
329
		  this.repositionWindow();
330
	  Cookie.set('ConsoleVisible', 'true')
331
 	  this.inputElement.select()
332
 	  this.hidden = false;
333
	},
334
 
335
	hide : function() {
336
	  this.hidden = true;
337
	  Element.hide(this.logElement)
338
	  Cookie.set('ConsoleVisible', 'false')
339
	},
340
 
341
	output : function(message, style) {
342
			// If we are at the bottom of the window, then keep scrolling with the output
343
			var shouldScroll = (this.outputElement.scrollTop + (2 * this.outputElement.clientHeight)) >= this.outputElement.scrollHeight
344
 
345
			this.outputCount++
346
	  	style = (style ? style += ';' : '')
347
	  	style += 'padding:1px;margin:0 0 5px 0'
348
 
349
		  if (this.outputCount % 2 == 0) style += ";background-color:#101010"
350
 
351
	  	message = message || "undefined"
352
	  	message = message.toString().escapeHTML()
353
 
354
	  	this.outputElement.innerHTML += "<pre style='" + style + "'>" + message + "</pre>"
355
 
356
	  	if (shouldScroll) {
357
				this.outputElement.scrollTop = this.outputElement.scrollHeight
358
			}
359
	},
360
 
361
	updateTags : function() {
362
		var pattern = this.tagFilterElement.value
363
 
364
		if (this.tagPattern == pattern) return
365
 
366
		try {
367
			new RegExp(pattern)
368
		}
369
		catch (e) {
370
			return
371
		}
372
 
373
		this.tagPattern = pattern
374
		Cookie.set('tagPattern', this.tagPattern)
375
 
376
		this.outputElement.innerHTML = ""
377
 
378
		// Go through each log entry again
379
		this.outputCount = 0;
380
		for (var i = 0; i < Logger.logEntries.length; i++) {
381
  		this.logUpdate(Logger.logEntries[i])
382
  	}
383
	},
384
 
385
	repositionWindow : function() {
386
		var offset = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
387
		var pageHeight = self.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
388
		this.logElement.style.top = (offset + pageHeight - Element.getHeight(this.logElement)) + "px"
389
	},
390
 
391
	// Event Handlers
392
	// --------------
393
 
394
	logUpdate : function(logEntry) {
395
		if (logEntry.tag.search(new RegExp(this.tagPattern, 'igm')) == -1) return
396
		var style = ''
397
	  if (logEntry.tag.search(/error/) != -1) style += 'color:red'
398
	  else if (logEntry.tag.search(/warning/) != -1) style += 'color:orange'
399
	  else if (logEntry.tag.search(/debug/) != -1) style += 'color:green'
400
 	  else if (logEntry.tag.search(/info/) != -1) style += 'color:white'
401
	  else style += 'color:yellow'
402
 
403
		this.output(logEntry.message, style)
404
	},
405
 
406
	clear : function(e) {
407
		this.outputElement.innerHTML = ""
408
	},
409
 
410
	handleInput : function(e) {
411
		if (e.keyCode == Event.KEY_RETURN ) {
412
	  	var command = this.inputElement.value
413
 
414
	  	switch(command) {
415
	    	case "clear":
416
	      		Logger.clear()
417
	      		break
418
 
419
	    	default:
420
	      	var consoleOutput = ""
421
 
422
	      	try {
423
	        	consoleOutput = eval(this.inputElement.value)
424
	      	}
425
	      	catch (e) {
426
	        	Logger.error("Problem parsing input <" + command + ">", e)
427
	        	break
428
					}
429
 
430
					Logger.log(consoleOutput)
431
	      	break
432
			}
433
 
434
	  	if (this.inputElement.value != "" && this.inputElement.value != this.commandHistory[0]) {
435
	    	this.commandHistory.unshift(this.inputElement.value)
436
	  	}
437
 
438
	  	this.commandIndex = 0
439
	  	this.inputElement.value = ""
440
		}
441
    else if (e.keyCode == Event.KEY_UP && this.commandHistory.length > 0) {
442
    	this.inputElement.value = this.commandHistory[this.commandIndex]
443
 
444
			if (this.commandIndex < this.commandHistory.length - 1) {
445
      	this.commandIndex += 1
446
      }
447
    }
448
    else if (e.keyCode == Event.KEY_DOWN && this.commandHistory.length > 0) {
449
    	if (this.commandIndex > 0) {
450
      	this.commandIndex -= 1
451
	    }
452
 
453
			this.inputElement.value = this.commandHistory[this.commandIndex]
454
	  }
455
 		else {
456
    		this.commandIndex = 0
457
    }
458
	}
459
};
460
 
461
 
462
// -------------------------
463
// Helper Functions And Junk
464
// -------------------------
465
function inspect(o)
466
{
467
	var objtype = typeof(o);
468
	if (objtype == "undefined") {
469
		return "undefined";
470
	} else if (objtype == "number" || objtype == "boolean") {
471
		return o + "";
472
	} else if (o === null) {
473
		return "null";
474
	}
475
 
476
	 try {
477
            var ostring = (o + "");
478
        } catch (e) {
479
            return "[" + typeof(o) + "]";
480
        }
481
 
482
	if (typeof(o) == "function")
483
	{
484
            o = ostring.replace(/^\s+/, "");
485
            var idx = o.indexOf("{");
486
            if (idx != -1) {
487
                o = o.substr(0, idx) + "{...}";
488
            }
489
			return o;
490
       }
491
 
492
	var reprString = function (o)
493
	{
494
		return ('"' + o.replace(/(["\\])/g, '\\$1') + '"'
495
			).replace(/[\f]/g, "\\f"
496
			).replace(/[\b]/g, "\\b"
497
			).replace(/[\n]/g, "\\n"
498
			).replace(/[\t]/g, "\\t"
499
			).replace(/[\r]/g, "\\r");
500
	};
501
 
502
	if (objtype == "string") {
503
		return reprString(o);
504
	}
505
	// recurse
506
	var me = arguments.callee;
507
	// short-circuit for objects that support "json" serialization
508
	// if they return "self" then just pass-through...
509
	var newObj;
510
	if (typeof(o.__json__) == "function") {
511
		newObj = o.__json__();
512
		if (o !== newObj) {
513
			return me(newObj);
514
		}
515
	}
516
	if (typeof(o.json) == "function") {
517
		newObj = o.json();
518
		if (o !== newObj) {
519
			return me(newObj);
520
		}
521
	}
522
	// array
523
	if (objtype != "function" && typeof(o.length) == "number") {
524
		var res = [];
525
		for (var i = 0; i < o.length; i++) {
526
			var val = me(o[i]);
527
			if (typeof(val) != "string") {
528
				val = "undefined";
529
			}
530
			res.push(val);
531
		}
532
		return "[" + res.join(", ") + "]";
533
	}
534
 
535
	// generic object code path
536
	res = [];
537
	for (var k in o) {
538
		var useKey;
539
		if (typeof(k) == "number") {
540
			useKey = '"' + k + '"';
541
		} else if (typeof(k) == "string") {
542
			useKey = reprString(k);
543
		} else {
544
			// skip non-string or number keys
545
			continue;
546
		}
547
		val = me(o[k]);
548
		if (typeof(val) != "string") {
549
			// skip non-serializable values
550
			continue;
551
		}
552
		res.push(useKey + ":" + val);
553
	}
554
	return "{" + res.join(", ") + "}";
555
};
556
 
557
Array.prototype.contains = function(object) {
558
	for(var i = 0; i < this.length; i++) {
559
		if (object == this[i]) return true
560
	}
561
 
562
	return false
563
};
564
 
565
// Helper Alias for simple logging
566
var puts = function() {return Logger.log(arguments[0], arguments[1])};
567
 
568
/*************************************
569
 
570
	Javascript Object Tree
571
	version 1.0
572
	last revision:04.11.2004
573
	steve@slayeroffice.com
574
	http://slayeroffice.com
575
 
576
	(c)2004 S.G. Chipman
577
 
578
	Please notify me of any modifications
579
	you make to this code so that I can
580
	update the version hosted on slayeroffice.com
581
 
582
 
583
************************************/
584
if(typeof Prado == "undefined")
585
	var Prado = {};
586
Prado.Inspector =
587
{
588
	d : document,
589
	types : new Array(),
590
	objs : new Array(),
591
	hidden : new Array(),
592
	opera : window.opera,
593
	displaying : '',
594
	nameList : new Array(),
595
 
596
	format : function(str) {
597
		if(typeof(str) != "string") return str;
598
		str=str.replace(/</g,"&lt;");
599
		str=str.replace(/>/g,"&gt;");
600
		return str;
601
	},
602
 
603
	parseJS : function(obj) {
604
		var name;
605
		if(typeof obj == "string") {  name = obj; obj = eval(obj); }
606
		win= typeof obj == 'undefined' ? window : obj;
607
		this.displaying = name ? name : win.toString();
608
		for(js in win) {
609
			try {
610
				if(win[js] && js.toString().indexOf("Inspector")==-1 && (win[js]+"").indexOf("[native code]")==-1) {
611
 
612
					t=typeof(win[js]);
613
					if(!this.objs[t.toString()]) {
614
						this.types[this.types.length]=t;
615
						this.objs[t]={};
616
						this.nameList[t] = new Array();
617
					}
618
					this.nameList[t].push(js);
619
					this.objs[t][js] = this.format(win[js]+"");
620
				}
621
			} catch(err) { }
622
		}
623
 
624
		for(i=0;i<this.types.length;i++)
625
			this.nameList[this.types[i]].sort();
626
	},
627
 
628
	show : function(objID) {
629
		this.d.getElementById(objID).style.display=this.hidden[objID]?"none":"block";
630
		this.hidden[objID]=this.hidden[objID]?0:1;
631
	},
632
 
633
	changeSpan : function(spanID) {
634
		if(this.d.getElementById(spanID).innerHTML.indexOf("+")>-1){
635
			this.d.getElementById(spanID).innerHTML="[-]";
636
		} else {
637
			this.d.getElementById(spanID).innerHTML="[+]";
638
		}
639
	},
640
 
641
	buildInspectionLevel : function()
642
	{
643
		var display = this.displaying;
644
		var list = display.split(".");
645
		var links = ["<a href=\"javascript:var_dump()\">[object Window]</a>"];
646
		var name = '';
647
		if(display.indexOf("[object ") >= 0) return links.join(".");
648
		for(var i = 0; i < list.length; i++)
649
		{
650
			name += (name.length ? "." : "") + list[i];
651
			links[i+1] = "<a href=\"javascript:var_dump('"+name+"')\">"+list[i]+"</a>";
652
		}
653
		return links.join(".");
654
	},
655
 
656
	buildTree : function() {
657
		mHTML = "<div>Inspecting "+this.buildInspectionLevel()+"</div>";
658
		mHTML +="<ul class=\"topLevel\">";
659
		this.types.sort();
660
		var so_objIndex=0;
661
		for(i=0;i<this.types.length;i++)
662
		{
663
			mHTML+="<li style=\"cursor:pointer;\" onclick=\"Prado.Inspector.show('ul"+i+"');Prado.Inspector.changeSpan('sp" + i + "')\"><span id=\"sp" + i + "\">[+]</span><b>" + this.types[i] + "</b> (" + this.nameList[this.types[i]].length + ")</li><ul style=\"display:none;\" id=\"ul"+i+"\">";
664
			this.hidden["ul"+i]=0;
665
			for(e=0;e<this.nameList[this.types[i]].length;e++)
666
			{
667
				var prop = this.nameList[this.types[i]][e];
668
				var value = this.objs[this.types[i]][prop]
669
				var more = "";
670
				if(value.indexOf("[object ") >= 0 && /^[a-zA-Z_]/.test(prop))
671
				{
672
					if(this.displaying.indexOf("[object ") < 0)
673
						more = " <a href=\"javascript:var_dump('"+this.displaying+"."+prop+"')\"><b>more</b></a>";
674
					else if(this.displaying.indexOf("[object Window]") >= 0)
675
						more = " <a href=\"javascript:var_dump('"+prop+"')\"><b>more</b></a>";
676
				}
677
				mHTML+="<li style=\"cursor:pointer;\" onclick=\"Prado.Inspector.show('mul" + so_objIndex + "');Prado.Inspector.changeSpan('sk" + so_objIndex + "')\"><span id=\"sk" + so_objIndex + "\">[+]</span>" + prop + "</li><ul id=\"mul" + so_objIndex + "\" style=\"display:none;\"><li style=\"list-style-type:none;\"><pre>" + value + more + "</pre></li></ul>";
678
				this.hidden["mul"+so_objIndex]=0;
679
				so_objIndex++;
680
			}
681
			mHTML+="</ul>";
682
		}
683
		mHTML+="</ul>";
684
		this.d.getElementById("so_mContainer").innerHTML =mHTML;
685
	},
686
 
687
	handleKeyEvent : function(e) {
688
		keyCode=document.all?window.event.keyCode:e.keyCode;
689
		if(keyCode==27) {
690
			this.cleanUp();
691
		}
692
	},
693
 
694
	cleanUp : function()
695
	{
696
		if(this.d.getElementById("so_mContainer"))
697
		{
698
			this.d.body.removeChild(this.d.getElementById("so_mContainer"));
699
			this.d.body.removeChild(this.d.getElementById("so_mStyle"));
700
			if(typeof Event != "undefined")
701
				Event.stopObserving(this.d, "keydown", this.dKeyDownEvent);
702
			this.types = new Array();
703
			this.objs = new Array();
704
			this.hidden = new Array();
705
		}
706
	},
707
 
708
	disabled : document.all && !this.opera,
709
 
710
	inspect : function(obj)
711
	{
712
		if(this.disabled)return alert("Sorry, this only works in Mozilla and Firefox currently.");
713
		this.cleanUp();
714
		mObj=this.d.body.appendChild(this.d.createElement("div"));
715
		mObj.id="so_mContainer";
716
		sObj=this.d.body.appendChild(this.d.createElement("style"));
717
		sObj.id="so_mStyle";
718
		sObj.type="text/css";
719
		sObj.innerHTML = this.style;
720
		this.dKeyDownEvent = this.handleKeyEvent.bind(this);
721
		if(typeof Event != "undefined")
722
			Event.observe(this.d, "keydown", this.dKeyDownEvent);
723
 
724
		this.parseJS(obj);
725
		this.buildTree();
726
 
727
		cObj=mObj.appendChild(this.d.createElement("div"));
728
		cObj.className="credits";
729
		cObj.innerHTML = "<b>[esc] to <a href=\"javascript:Prado.Inspector.cleanUp();\">close</a></b><br />Javascript Object Tree V2.0.";
730
 
731
		window.scrollTo(0,0);
732
	},
733
 
734
	style : "#so_mContainer { position:absolute; top:5px; left:5px; background-color:#E3EBED; text-align:left; font:9pt verdana; width:85%; border:2px solid #000; padding:5px; z-index:1000;  color:#000; } " +
735
			"#so_mContainer ul { padding-left:20px; } " +
736
			"#so_mContainer ul li { display:block; list-style-type:none; list-style-image:url(); line-height:2em; -moz-border-radius:.75em; font:10px verdana; padding:0; margin:2px; color:#000; } " +
737
			"#so_mContainer li:hover { background-color:#E3EBED; } " +
738
			"#so_mContainer ul li span { position:relative; width:15px; height:15px; margin-right:4px; } " +
739
			"#so_mContainer pre { background-color:#F9FAFB; border:1px solid #638DA1; height:auto; padding:5px; font:9px verdana; color:#000; } " +
740
			"#so_mContainer .topLevel { margin:0; padding:0; } " +
741
			"#so_mContainer .credits { float:left; width:200px; font:6.5pt verdana; color:#000; padding:2px; margin-left:5px; text-align:left; border-top:1px solid #000; margin-top:15px; width:75%; } " +
742
			"#so_mContainer .credits a { font:9px verdana; font-weight:bold; color:#004465; text-decoration:none; background-color:transparent; }"
743
};
744
 
745
//similar function to var_dump in PHP, brings up the javascript object tree UI.
746
function var_dump(obj)
747
{
748
	Prado.Inspector.inspect(obj);
749
}
750
 
751
//similar function to print_r for PHP
752
var print_r = inspect;
753