/[webpac2]/Webpacus/root/js/logger.js
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /Webpacus/root/js/logger.js

Parent Directory Parent Directory | Revision Log Revision Log


Revision 356 - (show annotations)
Sat Jan 7 23:43:33 2006 UTC (18 years, 3 months ago) by dpavlin
File MIME type: application/javascript
File size: 13512 byte(s)
 r380@llin:  dpavlin | 2006-01-08 00:33:55 +0100
 fixed warnings

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 var 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 var 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 },
154
155 debug : function(message) {
156 this.log(message, 'debug')
157 },
158
159 warn : function(message) {
160 this.log(message, 'warning')
161 },
162
163 error : function(message, error) {
164 this.log(message + ": \n" + error, 'error')
165 },
166
167 clear : function () {
168 this.logEntries = []
169 this.onclear.dispatch()
170 }
171 }
172
173 var LogEntry = Class.create()
174 LogEntry.prototype = {
175 initialize : function(message, tag) {
176 this.message = message
177 this.tag = tag
178 }
179 }
180
181 var LogConsole = Class.create()
182 LogConsole.prototype = {
183
184 // Properties
185 // ----------
186 commandHistory : [],
187 commandIndex : 0,
188
189 // Methods
190 // -------
191
192 initialize : function() {
193 this.outputCount = 0
194 this.tagPattern = Cookie.get('tagPattern') || ".*"
195
196 // I hate writing javascript in HTML... but what's a better alternative
197 this.logElement = document.createElement('div')
198 document.body.appendChild(this.logElement)
199 Element.hide(this.logElement)
200
201 this.logElement.style.position = "absolute"
202 this.logElement.style.left = '0px'
203 this.logElement.style.width = '100%'
204
205 this.logElement.style.textAlign = "left"
206 this.logElement.style.fontFamily = "lucida console"
207 this.logElement.style.fontSize = "100%"
208 this.logElement.style.backgroundColor = 'darkgray'
209 this.logElement.style.opacity = 0.9
210 this.logElement.style.zIndex = 2000
211
212 // Add toolbarElement
213 this.toolbarElement = document.createElement('div')
214 this.logElement.appendChild(this.toolbarElement)
215 this.toolbarElement.style.padding = "0 0 0 2px"
216
217 // Add buttons
218 this.buttonsContainerElement = document.createElement('span')
219 this.toolbarElement.appendChild(this.buttonsContainerElement)
220
221 this.buttonsContainerElement.innerHTML += '<button onclick="logConsole.toggle()" style="float:right;color:black">close</button>'
222 this.buttonsContainerElement.innerHTML += '<button onclick="Logger.clear()" style="float:right;color:black">clear</button>'
223
224
225 //Add Tag Filter
226 this.tagFilterContainerElement = document.createElement('span')
227 this.toolbarElement.appendChild(this.tagFilterContainerElement)
228 this.tagFilterContainerElement.style.cssFloat = 'left'
229 this.tagFilterContainerElement.appendChild(document.createTextNode("Log Filter"))
230
231 this.tagFilterElement = document.createElement('input')
232 this.tagFilterContainerElement.appendChild(this.tagFilterElement)
233 this.tagFilterElement.style.width = '200px'
234 this.tagFilterElement.value = this.tagPattern
235 this.tagFilterElement.setAttribute('autocomplete', 'off') // So Firefox doesn't flip out
236
237 Event.observe(this.tagFilterElement, 'keyup', this.updateTags.bind(this))
238 Event.observe(this.tagFilterElement, 'click', function() {this.tagFilterElement.select()}.bind(this))
239
240 // Add outputElement
241 this.outputElement = document.createElement('div')
242 this.logElement.appendChild(this.outputElement)
243 this.outputElement.style.overflow = "auto"
244 this.outputElement.style.clear = "both"
245 this.outputElement.style.height = "200px"
246 this.outputElement.style.backgroundColor = 'black'
247
248 this.inputContainerElement = document.createElement('div')
249 this.inputContainerElement.style.width = "100%"
250 this.logElement.appendChild(this.inputContainerElement)
251
252 this.inputElement = document.createElement('input')
253 this.inputContainerElement.appendChild(this.inputElement)
254 this.inputElement.style.width = '100%'
255 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
256 this.inputElement.style.margin = '0px'
257 this.inputElement.style.padding = '0px'
258 this.inputElement.value = 'Type command here'
259 this.inputElement.setAttribute('autocomplete', 'off') // So Firefox doesn't flip out
260
261 Event.observe(this.inputElement, 'keyup', this.handleInput.bind(this))
262 Event.observe(this.inputElement, 'click', function() {this.inputElement.select()}.bind(this))
263
264 window.setInterval(this.repositionWindow.bind(this), 500)
265 this.repositionWindow()
266
267 // Listen to the logger....
268 Logger.onupdate.addListener(this.logUpdate.bind(this))
269 Logger.onclear.addListener(this.clear.bind(this))
270
271 // Preload log element with the log entries that have been entered
272 for (var i = 0; i < Logger.logEntries.length; i++) {
273 this.logUpdate(Logger.logEntries[i])
274 }
275
276 // Feed all errors into the logger (For some unknown reason I can only get this to work
277 // with an inline event declaration)
278 Event.observe(window, 'error', function(msg, url, lineNumber) {Logger.error("Error in (" + (url || location) + ") on line "+lineNumber+"", msg)})
279
280 // Allow acess key link
281 var accessElement = document.createElement('span')
282 accessElement.innerHTML = '<button style="position:absolute;top:-100px" onclick="javascript:logConsole.toggle()" accesskey="d"></button>'
283 document.body.appendChild(accessElement)
284
285 if (Cookie.get('ConsoleVisible') == 'true') {
286 this.toggle()
287 }
288 },
289
290 toggle : function() {
291 if (this.logElement.style.display == 'none') {
292 this.show()
293 }
294 else {
295 this.hide()
296 }
297 },
298
299 show : function() {
300 Element.show(this.logElement)
301 this.outputElement.scrollTop = this.outputElement.scrollHeight // Scroll to bottom when toggled
302 Cookie.set('ConsoleVisible', 'true')
303 this.inputElement.select()
304 },
305
306 hide : function() {
307 Element.hide(this.logElement)
308 Cookie.set('ConsoleVisible', 'false')
309 },
310
311 output : function(message, style) {
312 // If we are at the bottom of the window, then keep scrolling with the output
313 var shouldScroll = (this.outputElement.scrollTop + (2 * this.outputElement.clientHeight)) >= this.outputElement.scrollHeight
314
315 this.outputCount++
316 style = (style ? style += ';' : '')
317 style += 'padding:1px;margin:0 0 5px 0'
318
319 if (this.outputCount % 2 == 0) style += ";background-color:#101010"
320
321 message = message || "undefined"
322 message = message.toString().escapeHTML()
323
324 this.outputElement.innerHTML += "<pre style='" + style + "'>" + message + "</pre>"
325
326 if (shouldScroll) {
327 this.outputElement.scrollTop = this.outputElement.scrollHeight
328 }
329 },
330
331 updateTags : function() {
332 var pattern = this.tagFilterElement.value
333
334 if (this.tagPattern == pattern) return
335
336 try {
337 new RegExp(pattern)
338 }
339 catch (e) {
340 return
341 }
342
343 this.tagPattern = pattern
344 Cookie.set('tagPattern', this.tagPattern)
345
346 this.outputElement.innerHTML = ""
347
348 // Go through each log entry again
349 this.outputCount = 0;
350 for (var i = 0; i < Logger.logEntries.length; i++) {
351 this.logUpdate(Logger.logEntries[i])
352 }
353 },
354
355 repositionWindow : function() {
356 var offset = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
357 var pageHeight = self.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
358 this.logElement.style.top = (offset + pageHeight - Element.getHeight(this.logElement)) + "px"
359 },
360
361 // Event Handlers
362 // --------------
363
364 logUpdate : function(logEntry) {
365 if (logEntry.tag.search(new RegExp(this.tagPattern, 'igm')) == -1) return
366 var style = ''
367 if (logEntry.tag.search(/error/) != -1) style += 'color:red'
368 else if (logEntry.tag.search(/warning/) != -1) style += 'color:orange'
369 else if (logEntry.tag.search(/debug/) != -1) style += 'color:green'
370 else if (logEntry.tag.search(/info/) != -1) style += 'color:white'
371 else style += 'color:yellow'
372
373 this.output(logEntry.message, style)
374 },
375
376 clear : function(e) {
377 this.outputElement.innerHTML = ""
378 },
379
380 handleInput : function(e) {
381 if (e.keyCode == Event.KEY_RETURN ) {
382 var command = this.inputElement.value
383
384 switch(command) {
385 case "clear":
386 Logger.clear()
387 break
388
389 default:
390 var consoleOutput = ""
391
392 try {
393 consoleOutput = eval(this.inputElement.value)
394 }
395 catch (e) {
396 Logger.error("Problem parsing input <" + command + ">", e)
397 break
398 }
399
400 Logger.log(consoleOutput)
401 break
402 }
403
404 if (this.inputElement.value != "" && this.inputElement.value != this.commandHistory[0]) {
405 this.commandHistory.unshift(this.inputElement.value)
406 }
407
408 this.commandIndex = 0
409 this.inputElement.value = ""
410 }
411 else if (e.keyCode == Event.KEY_UP && this.commandHistory.length > 0) {
412 this.inputElement.value = this.commandHistory[this.commandIndex]
413
414 if (this.commandIndex < this.commandHistory.length - 1) {
415 this.commandIndex += 1
416 }
417 }
418 else if (e.keyCode == Event.KEY_DOWN && this.commandHistory.length > 0) {
419 if (this.commandIndex > 0) {
420 this.commandIndex -= 1
421 }
422
423 this.inputElement.value = this.commandHistory[this.commandIndex]
424 }
425 else {
426 this.commandIndex = 0
427 }
428 }
429 }
430
431 // Load the Console when the window loads
432 var logConsole = null;
433 Event.observe(window, "load", function() {logConsole = new LogConsole()})
434
435 // -------------------------
436 // Helper Functions And Junk
437 // -------------------------
438 function inspect(element, hideProperties, hideMethods) {
439 var properties = []
440 var methods = []
441
442 element = $(element)
443
444 for(var internal in element) {
445 try {
446 if (element[internal] instanceof Function) {
447 if (!hideMethods) methods.push(internal + ":\t" + element[internal] )
448 }
449 else {
450 if (!hideProperties) properties.push(internal + ":\t" + element[internal] )
451 }
452 }
453 catch (e) {
454 Logger.error("Excetion thrown while inspecting object.", e)
455 }
456 }
457
458 properties.sort()
459 methods.sort()
460
461 var internals = properties.concat(methods)
462 var output = ""
463 for (var i = 0; i < internals.length; i++) {
464 output += (internals[i] + "\n")
465 }
466
467 return output
468 }
469
470 Array.prototype.contains = function(object) {
471 for(var i = 0; i < this.length; i++) {
472 if (object == this[i]) return true
473 }
474
475 return false
476 }
477
478 // Helper Alias for simple logging
479 var puts = function() {return Logger.log(arguments[0], arguments[1])}

  ViewVC Help
Powered by ViewVC 1.1.26