/[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

Annotation of /Webpacus/root/js/logger.js

Parent Directory Parent Directory | Revision Log Revision Log


Revision 134 - (hide annotations)
Thu Nov 24 16:30:16 2005 UTC (18 years, 5 months ago) by dpavlin
File MIME type: application/javascript
File size: 13472 byte(s)
 r9104@llin:  dpavlin | 2005-11-24 17:32:00 +0100
 first try at re-implementing editor in Prototype and script.aculo.us and
 mir.aculo.us, it's not as easy as it seems.

1 dpavlin 134 /*
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     },
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     LogEntry = Class.create()
174     LogEntry.prototype = {
175     initialize : function(message, tag) {
176     this.message = message
177     this.tag = tag
178     }
179     }
180    
181     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     Event.observe(window, "load", function() {logConsole = new LogConsole()})
433    
434     // -------------------------
435     // Helper Functions And Junk
436     // -------------------------
437     function inspect(element, hideProperties, hideMethods) {
438     var properties = []
439     var methods = []
440    
441     element = $(element)
442    
443     for(var internal in element) {
444     try {
445     if (element[internal] instanceof Function) {
446     if (!hideMethods) methods.push(internal + ":\t" + element[internal] )
447     }
448     else {
449     if (!hideProperties) properties.push(internal + ":\t" + element[internal] )
450     }
451     }
452     catch (e) {
453     Logger.error("Excetion thrown while inspecting object.", e)
454     }
455     }
456    
457     properties.sort()
458     methods.sort()
459    
460     var internals = properties.concat(methods)
461     var output = ""
462     for (var i = 0; i < internals.length; i++) {
463     output += (internals[i] + "\n")
464     }
465    
466     return output
467     }
468    
469     Array.prototype.contains = function(object) {
470     for(var i = 0; i < this.length; i++) {
471     if (object == this[i]) return true
472     }
473    
474     return false
475     }
476    
477     // Helper Alias for simple logging
478     var puts = function() {return Logger.log(arguments[0], arguments[1])}

  ViewVC Help
Powered by ViewVC 1.1.26