5 See <http://mochikit.com/> for documentation, downloads, license, etc.
7 (c) 2005 Bob Ippolito. All rights Reserved.
11 if (typeof(dojo
) != 'undefined') {
12 dojo
.provide('MochiKit.Logging');
13 dojo
.require('MochiKit.Base');
16 if (typeof(JSAN
) != 'undefined') {
17 JSAN
.use("MochiKit.Base", []);
21 if (typeof(MochiKit
.Base
) == 'undefined') {
25 throw "MochiKit.Logging depends on MochiKit.Base!";
28 if (typeof(MochiKit
.Logging
) == 'undefined') {
29 MochiKit
.Logging
= {};
32 MochiKit
.Logging
.NAME
= "MochiKit.Logging";
33 MochiKit
.Logging
.VERSION
= "1.4";
34 MochiKit
.Logging
.__repr__
= function () {
35 return "[" + this.NAME
+ " " + this.VERSION
+ "]";
38 MochiKit
.Logging
.toString
= function () {
39 return this.__repr__();
43 MochiKit
.Logging
.EXPORT
= [
57 MochiKit
.Logging
.EXPORT_OK
= [
64 /** @id MochiKit.Logging.LogMessage */
65 MochiKit
.Logging
.LogMessage
= function (num
, level
, info
) {
69 this.timestamp
= new Date();
72 MochiKit
.Logging
.LogMessage
.prototype = {
73 /** @id MochiKit.Logging.LogMessage.prototype.repr */
75 var m
= MochiKit
.Base
;
76 return 'LogMessage(' +
79 [this.num
, this.level
, this.info
]
82 /** @id MochiKit.Logging.LogMessage.prototype.toString */
83 toString
: MochiKit
.Base
.forwardCall("repr")
86 MochiKit
.Base
.update(MochiKit
.Logging
, {
87 /** @id MochiKit.Logging.logLevelAtLeast */
88 logLevelAtLeast
: function (minLevel
) {
89 var self
= MochiKit
.Logging
;
90 if (typeof(minLevel
) == 'string') {
91 minLevel
= self
.LogLevel
[minLevel
];
93 return function (msg
) {
94 var msgLevel
= msg
.level
;
95 if (typeof(msgLevel
) == 'string') {
96 msgLevel
= self
.LogLevel
[msgLevel
];
98 return msgLevel
>= minLevel
;
102 /** @id MochiKit.Logging.isLogMessage */
103 isLogMessage
: function (/* ... */) {
104 var LogMessage
= MochiKit
.Logging
.LogMessage
;
105 for (var i
= 0; i
< arguments
.length
; i
++) {
106 if (!(arguments
[i
] instanceof LogMessage
)) {
113 /** @id MochiKit.Logging.compareLogMessage */
114 compareLogMessage
: function (a
, b
) {
115 return MochiKit
.Base
.compare([a
.level
, a
.info
], [b
.level
, b
.info
]);
118 /** @id MochiKit.Logging.alertListener */
119 alertListener
: function (msg
) {
122 "\nlevel: " + msg
.level
+
123 "\ninfo: " + msg
.info
.join(" ")
129 /** @id MochiKit.Logging.Logger */
130 MochiKit
.Logging
.Logger
= function (/* optional */maxSize
) {
132 if (typeof(maxSize
) == 'undefined' || maxSize
=== null) {
135 this.maxSize
= maxSize
;
138 this.useNativeConsole
= false;
141 MochiKit
.Logging
.Logger
.prototype = {
142 /** @id MochiKit.Logging.Logger.prototype.clear */
144 this._messages
.splice(0, this._messages
.length
);
147 /** @id MochiKit.Logging.Logger.prototype.logToConsole */
148 logToConsole
: function (msg
) {
149 if (typeof(window
) != "undefined" && window
.console
150 && window
.console
.log
) {
151 // Safari and FireBug 0.4
152 // Percent replacement is a workaround for cute Safari crashing bug
153 window
.console
.log(msg
.replace(/%/g, '\uFF05'));
154 } else if (typeof(opera
) != "undefined" && opera
.postError
) {
156 opera
.postError(msg
);
157 } else if (typeof(printfire
) == "function") {
158 // FireBug 0.3 and earlier
160 } else if (typeof(Debug
) != "undefined" && Debug
.writeln
) {
161 // IE Web Development Helper (?)
162 // http://www.nikhilk.net/Entry
.aspx
?id
=93
164 } else if (typeof(debug
) != "undefined" && debug
.trace
) {
165 // Atlas framework (?)
166 // http://www.nikhilk.net/Entry
.aspx
?id
=93
171 /** @id MochiKit.Logging.Logger.prototype.dispatchListeners */
172 dispatchListeners
: function (msg
) {
173 for (var k
in this.listeners
) {
174 var pair
= this.listeners
[k
];
175 if (pair
.ident
!= k
|| (pair
[0] && !pair
[0](msg
))) {
182 /** @id MochiKit.Logging.Logger.prototype.addListener */
183 addListener
: function (ident
, filter
, listener
) {
184 if (typeof(filter
) == 'string') {
185 filter
= MochiKit
.Logging
.logLevelAtLeast(filter
);
187 var entry
= [filter
, listener
];
189 this.listeners
[ident
] = entry
;
192 /** @id MochiKit.Logging.Logger.prototype.removeListener */
193 removeListener
: function (ident
) {
194 delete this.listeners
[ident
];
197 /** @id MochiKit.Logging.Logger.prototype.baseLog */
198 baseLog
: function (level
, message
/*, ...*/) {
199 var msg
= new MochiKit
.Logging
.LogMessage(
202 MochiKit
.Base
.extend(null, arguments
, 1)
204 this._messages
.push(msg
);
205 this.dispatchListeners(msg
);
206 if (this.useNativeConsole
) {
207 this.logToConsole(msg
.level
+ ": " + msg
.info
.join(" "));
210 while (this.maxSize
>= 0 && this._messages
.length
> this.maxSize
) {
211 this._messages
.shift();
215 /** @id MochiKit.Logging.Logger.prototype.getMessages */
216 getMessages
: function (howMany
) {
218 if (!(typeof(howMany
) == 'undefined' || howMany
=== null)) {
219 firstMsg
= Math
.max(0, this._messages
.length
- howMany
);
221 return this._messages
.slice(firstMsg
);
224 /** @id MochiKit.Logging.Logger.prototype.getMessageText */
225 getMessageText
: function (howMany
) {
226 if (typeof(howMany
) == 'undefined' || howMany
=== null) {
229 var messages
= this.getMessages(howMany
);
230 if (messages
.length
) {
231 var lst
= map(function (m
) {
232 return '\n [' + m
.num
+ '] ' + m
.level
+ ': ' + m
.info
.join(' ');
234 lst
.unshift('LAST ' + messages
.length
+ ' MESSAGES:');
240 /** @id MochiKit.Logging.Logger.prototype.debuggingBookmarklet */
241 debuggingBookmarklet
: function (inline
) {
242 if (typeof(MochiKit
.LoggingPane
) == "undefined") {
243 alert(this.getMessageText());
245 MochiKit
.LoggingPane
.createLoggingPane(inline
|| false);
250 MochiKit
.Logging
.__new__
= function () {
259 var m
= MochiKit
.Base
;
260 m
.registerComparator("LogMessage",
262 this.compareLogMessage
265 var partial
= m
.partial
;
267 var Logger
= this.Logger
;
268 var baseLog
= Logger
.prototype.baseLog
;
269 m
.update(this.Logger
.prototype, {
270 debug
: partial(baseLog
, 'DEBUG'),
271 log
: partial(baseLog
, 'INFO'),
272 error
: partial(baseLog
, 'ERROR'),
273 fatal
: partial(baseLog
, 'FATAL'),
274 warning
: partial(baseLog
, 'WARNING')
277 // indirectly find logger so it can be replaced
279 var connectLog
= function (name
) {
281 self
.logger
[name
].apply(self
.logger
, arguments
);
285 /** @id MochiKit.Logging.log */
286 this.log
= connectLog('log');
287 /** @id MochiKit.Logging.logError */
288 this.logError
= connectLog('error');
289 /** @id MochiKit.Logging.logDebug */
290 this.logDebug
= connectLog('debug');
291 /** @id MochiKit.Logging.logFatal */
292 this.logFatal
= connectLog('fatal');
293 /** @id MochiKit.Logging.logWarning */
294 this.logWarning
= connectLog('warning');
295 this.logger
= new Logger();
296 this.logger
.useNativeConsole
= true;
299 ":common": this.EXPORT
,
300 ":all": m
.concat(this.EXPORT
, this.EXPORT_OK
)
303 m
.nameFunctions(this);
307 if (typeof(printfire
) == "undefined" &&
308 typeof(document
) != "undefined" && document
.createEvent
&&
309 typeof(dispatchEvent
) != "undefined") {
310 // FireBug really should be less lame about this global function
311 printfire
= function () {
312 printfire
.args
= arguments
;
313 var ev
= document
.createEvent("Events");
314 ev
.initEvent("printfire", false, true);
319 MochiKit
.Logging
.__new__();
321 MochiKit
.Base
._exportSymbols(this, MochiKit
.Logging
);