1 
  2 /**
  3  * @name	CeL log function
  4  * @fileoverview
  5  * 本檔案包含了記錄用 functions。
  6  * @since	2009/11/17
  7  * @see
  8  * <a href="http://getfirebug.com/lite.html" accessdate="2010/1/1 14:54">Firebug Lite</a>,
  9  * <a href="http://www.mozilla.org/projects/venkman/" accessdate="2010/1/1 16:43">Venkman JavaScript Debugger project page</a>
 10  */
 11 
 12 //	http://blogs.msdn.com/b/webdevtools/archive/2007/03/02/jscript-intellisense-in-orcas.aspx
 13 ///	<reference path="../ce.js"/>
 14 
 15 /*
 16 TODO:
 17 emergency/urgent situation alert
 18 會盡量以網頁上方/頂部黄色的導航條/警告條展示
 19 「不再顯示」功能
 20 .format()
 21 	將 div format 成 log panel。
 22 分群, http://developer.yahoo.com/yui/examples/uploader/uploader-simple-button.html
 23 */
 24 
 25 
 26 
 27 //WScript.Echo(this.Class);
 28 
 29 //	若 library base 尚未 load 或本 module 已經 loaded 則跳過。
 30 if (typeof CeL === 'function')
 31 (function(){
 32 
 33 /**
 34  * 本 module 之 name(id),<span style="text-decoration:line-through;">不設定時會從呼叫時之 path 取得</span>。
 35  * @type	String
 36  * @constant
 37  * @inner
 38  * @ignore
 39  */
 40 var module_name = 'application.debug.log';
 41 
 42 //var do_before_including = function() {};
 43 
 44 /*	to include:
 45 	include code_for_including
 46 	<div id="debug_panel"></div>
 47 	var SL=new Debug.log('debug_panel'),sl=function(){SL.log.apply(SL,arguments);},err=function(){SL.err.apply(SL,arguments);},warn=function(){SL.warn.apply(SL,arguments);};
 48 
 49 	http://www.comsharp.com/GetKnowledge/zh-CN/TeamBlogTimothyPage_K742.aspx
 50 
 51 	if possible, use Firebug Lite instead.
 52 	http://benalman.com/projects/javascript-debug-console-log/
 53 */
 54 
 55 
 56 //	===================================================
 57 /**
 58  * 若欲 include 整個 module 時,需囊括之 code。通常即 CeL。
 59  * @type	Function
 60  * @param	{Function} library_namespace	namespace of library
 61  * @param	load_arguments	呼叫時之 argument(s)
 62  * @return
 63  * @constant
 64  * @inner
 65  * @ignore
 66  */
 67 var code_for_including = function(library_namespace, load_arguments) {
 68 //WScript.Echo(this);
 69 
 70 var
 71 
 72 //	class private	-----------------------------------
 73 
 74 //	class name, 需要用到這個都不是好方法。
 75 //cn='Debug.log',
 76 
 77 /**
 78  * private storage pool
 79  * @ignore
 80  */
 81 p=[],
 82 
 83 log_data = function(m, l) {
 84 	this.m = m;
 85 	this.l = l;
 86 	return this;
 87 },
 88 
 89 /**
 90  * default write/show log function
 91  * @ignore
 92  * @param	{string} id	element id
 93  */
 94 w = function(id) {
 95 	var o, m, c, _p = p[id], _t = _p.instance,
 96 	/**
 97 	 * buffer
 98 	 * @inner
 99 	 * @ignore
100 	 */
101 	b = _p.buf,
102 	B = _p.board, F = _p.do_function, level;
103 
104 	if (_p.clean)
105 		_t.clear(), _p.clean = 0;
106 
107 	if (!B && !F)
108 		return;
109 
110 	while (b.length){
111 		// 預防 MP 時重複顯示
112 		m = b.shift();
113 
114 		if (F)
115 			F(m);
116 
117 		//	IE8: 'constructor' 是 null 或不是一個物件
118 		try {
119 			c = m.constructor;
120 			// alert((m.constructor === log_data) + '\n' + m.constructor + '\n' + m);
121 		} catch (e) {
122 		}
123 		if (c === log_data) {
124 			if (!isNaN(m.l) && m.l < library_namespace.set_debug())
125 				continue;
126 			c = m.l in _t.className_set ? m.l : 0;
127 			m = m.m;
128 			if (c in _t.message_prefix)
129 				m = _t.message_prefix[c] + m;
130 			c = _t.className_set[c];
131 		} else {
132 			//	add default style set
133 			if (c = _t.message_prefix.log)
134 				m = c + m;
135 			c = _t.className_set.log || 0;
136 		}
137 		_p.lbuf.push(m);
138 
139 		if (B) { // && typeof document==='object'
140 			o = _p.instance.log_tag;
141 			if (o) {
142 				o = document.createElement(o);
143 				if (c)
144 					o.className = c;
145 
146 				o.innerHTML = typeof m === 'string' ?
147 						// for character (null)
148 						m.replace(/\x00/g,
149 						'<span class="control_character">\\x00</span>')
150 						//	'­' (hyphen) 這符號(連字符)可以自動斷行,並在斷行時自動加上個橫槓。在顯示長整數時較有用。
151 						.replace(/(\d{20})/g,'$1­')
152 						: m;
153 			} else
154 				o = document.createTextNode(m);
155 			B.appendChild(o);
156 		}
157 	}
158 
159 	//if(_t.auto_hide)B.style.display=B.innerHTML?'block':'none';
160 	if (B && _t.auto_scroll)
161 		B.scrollTop = B.scrollHeight - B.clientHeight;
162 },
163 
164 
165 /**
166  * save log
167  * @ignore
168  * @param	m	message
169  * @param	{string} id	element id
170  * @param	force	force to clean the message area
171  */
172 s = function(m, id, force) {
173 	var _p = p[id], _t = _p.instance, f = _p.logF, s = _t.save_log;
174 	if (!s || typeof s === 'function' && !s(m, l))
175 		return;
176 
177 	if (m)
178 		_p.sbuf.push(m = (_t.save_date && typeof gDate == 'function' ? _t.save_new_line
179 				+ gDate() + _t.save_new_line
180 				: '')
181 				+ m);
182 
183 	if (force || _t.flush || _p.sbufL > _t.save_limit)
184 		try {
185 			if (f
186 					|| _t.log_file
187 					&& (f = _p.logF = fso.OpenTextFile(_t.log_file,
188 							8/* ForAppending */, true/* create */,
189 							_t.log_encoding)))
190 				f.Write(_p.sbuf.join(_t.save_new_line)), _p.sbuf = [],
191 						_p.sbufL = 0, _t.error_message = 0;
192 		} catch (e) {
193 			_t.error_message = e;// err(e);
194 		}
195 	else if (m)
196 		_p.sbufL += m.length;
197 },
198 
199 //	instance constructor	---------------------------
200 //	(document object)
201 /*
202 
203 _=this
204 
205 
206 TODO:
207 set class in each input
208 input array
209 show file path & directory functional	可從 FSO operation.hta 移植
210 增加 group 以便在多次輸入時亦可 toggle 或排版
211 
212 count
213 c.f.: GLog
214 
215 dependency:
216 
217 */
218 /**
219  * initial a log tool's instance/object
220  * @class	log function
221  * @see	usage: <a href="#.extend">CeL.application.debug.log.extend</a>
222  * @since	2008/8/20 23:9:48
223  * @requires	gDate(),NewLine,fso
224 
225  * @constructor
226  * @name	CeL.application.debug.log
227  * @param	{String|object HTMLElement} obj	log target: message area element or id
228  * @param	{Object} [className_set]	class name set
229  */
230 _tmp;CeL.application.debug.log
231 = function(obj, className_set) {
232 	// Initial instance object. You can set it yourself.
233 	/**
234 	 * log 時 warning/error message 之 className
235 	 * @name	CeL.application.debug.log.prototype.className_set
236 	 */
237 	this.className_set = className_set || {
238 			/**
239 			 * @description	當呼叫 {@link CeL.application.debug.log.prototype.log} 時使用的 className, DEFAULT className.
240 			 * @name	CeL.application.debug.log.prototype.className_set.log
241 			 */
242 			log : 'debug_log',
243 			/**
244 			 * @description	當呼叫 {@link CeL.application.debug.log.prototype.warn} 時使用的 className
245 			 * @name	CeL.application.debug.log.prototype.className_set.warn
246 			 */
247 			warn : 'debug_warn',
248 			/**
249 			 * @description	當呼叫 {@link CeL.application.debug.log.prototype.err} 時使用的 className
250 			 * @name	CeL.application.debug.log.prototype.className_set.err
251 			 */
252 			err : 'debug_err',
253 			/**
254 			 * @description	當呼叫 {@link CeL.application.debug.log.prototype.set_board} 時設定 log panel 使用的 className
255 			 * @name	CeL.application.debug.log.prototype.className_set.panel
256 			 */
257 			panel : 'debug_panel'
258 	};
259 
260 	/**
261 	 * log 時 warning/error message 之 prefix
262 	 * @name	CeL.application.debug.log.prototype.message_prefix
263 	 */
264 	this.message_prefix = {
265 			/**
266 			 * @description	當呼叫 {@link CeL.application.debug.log.prototype.log} 時使用的 prefix, DEFAULT prefix.
267 			 * @name	CeL.application.debug.log.prototype.message_prefix.log
268 			 */
269 			log : '',
270 			/**
271 			 * @description	當呼叫 {@link CeL.application.debug.log.prototype.warn} 時使用的 prefix
272 			 * @name	CeL.application.debug.log.prototype.message_prefix.warn
273 			 */
274 			warn : '',
275 			/**
276 			 * @description	表示當呼叫 {@link CeL.application.debug.log.prototype.err}, 是錯誤 error message 時使用的 prefix
277 			 * @name	CeL.application.debug.log.prototype.message_prefix.err
278 			 */
279 			err : '<em>!! Error !!</em> '
280 	};
281 
282 	this.id = p.length;
283 	p.push( {
284 		instance : this,
285 		/**
286 		 * write buffer
287 		 */
288 		buf : [],
289 		/**
290 		 * save buffer when we need to save the messages
291 		 */
292 		sbuf : [],
293 		/**
294 		 * length of save buffer
295 		 */
296 		sbufL : 0,
297 		/**
298 		 * now logged buffer
299 		 */
300 		lbuf : []
301 	}); 
302 	this.set_board(obj);
303 };
304 
305 
306 
307 //	class public interface	---------------------------
308 
309 CeL.application.debug.log
310 .
311 /**
312  * do the log action
313  * @memberOf	CeL.application.debug.log
314  * @private
315  */
316 do_log = function(id) {
317 /*	這段應該只在 module namespace 重複定義時才會發生
318  var I=p[id];
319  if(!I){
320   alert('.do_log: not exist: ['+id+']');
321   return;
322  }
323  I=I.instance;
324 */
325 	var I = p[id].instance;
326 	if (I.do_log)
327 		I.do_log();
328 };
329 
330 
331 CeL.application.debug.log
332 .
333 /**
334  * 對各種不同 error object 作應對,獲得可理解的 error message。
335  * @param	e	error object
336  * @param	new_line	new_line
337  * @param	caller	function caller
338  * @memberOf	CeL.application.debug.log
339  * @see
340  * http://msdn.microsoft.com/en-us/library/ms976144.aspx
341  * The facility code establishes who originated the error. For example, all internal script engine errors generated by the JScript engine have a facility code of "A".
342  * http://msdn.microsoft.com/en-us/library/ms690088(VS.85).aspx
343  * 
344  * http://msdn.microsoft.com/en-us/library/t9zk6eay.aspx
345  * http://msdn.microsoft.com/en-us/library/microsoft.jscript.errorobject.aspx
346  * Specifies the name of the type of the error.
347  * Possible values include Error, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, and URIError.
348  */
349 get_error_message = function get_error_message(e, new_line, caller) {
350 	if (!new_line)
351 		new_line = _.prototype.save_new_line;
352 
353 	if (!caller || typeof caller !== 'string'){
354 		if (typeof caller !== 'function')
355 			try {
356 				// TODO: do not use .caller
357 				caller = get_error_message.caller;
358 			} catch (e) {
359 			}
360 
361 		if (caller === null)
362 			caller = 'from the top level';
363 		else if (typeof caller === 'function')
364 			caller = '@' + (library_namespace.get_function_name(caller) || caller);
365 		else
366 			caller = '@' + library_namespace.Class;
367 	}
368 
369 
370 	// from popErr()
371 	//	type
372 	var T = library_namespace.is_type(e),
373 	//	message
374 	m = T === 'Error' ?
375 			'Error ' + caller + ': '
376 			//	http://msdn.microsoft.com/en-us/library/cc231198(PROT.10).aspx
377 			//	<a href="http://msdn.microsoft.com/en-us/library/ms819773.aspx">Winerror.h</a>: error code definitions for the Win32 API functions
378 			//	(e.number & 0xFFFF): See 錯誤代碼 /錯誤提示碼 <a href="http://msdn.microsoft.com/en-us/library/ms681381%28VS.85%29.aspx">System Error Codes</a>
379 			//	http://social.msdn.microsoft.com/Search/zh-TW/?Query=%22System+Error+Codes%22+740&AddEnglish=1
380 			//	http://msdn.microsoft.com/en-us/library/aa394559(VS.85).aspx
381 			//	net helpmsg (e.number & 0xFFFF)
382 			+ (e.number & 0xFFFF) + (e.name ? ' [' + e.name + '] ' : ' ')
383 			+ '(facility code ' + (e.number >> 16 & 0x1FFF) + '): '
384 			+ new_line
385 			+ (e.message || '').replace(/\r?\n/g, '<br/>')
386 			//	.message 為主,.description 是舊的。
387 			+ (!e.description || e.description === e.message ?
388 				'' :
389 				new_line
390 					+ new_line
391 					+ ('' + e.description).replace(/\r?\n/g, '<br/>')
392 			)
393 
394 		: T === 'DOMException'?
395 			//	http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-17189187
396 			'[' + T + '] ' + e.code + ': ' + e.message
397 
398 		: !e || T === 'string' ? e
399 
400 		: '[' + T + '] ' + (e.message || e);
401 
402 
403 	if (library_namespace.is_debug(2) && typeof e === 'object' && e)
404 		for (T in e)
405 			try{
406 				//	Firefox has (new Error).stack
407 				//	http://eriwen.com/javascript/js-stack-trace/
408 				m += '<br/> <span class="debug_debug">' + T + '</span>: '
409 						+ (typeof e[T] === 'string' && T === 'stack' ?
410 								e[T].replace(/[\r\n]+$/, '').replace(/(@)([a-z\-]+:\/\/.+)(:)(\d+)$/gm, '$1<a href="view-source:$2#$4" target="_blank">$2</a>$3$4').replace(/\n/g, '<br/>- ')
411 								: typeof e[T] === 'string' && T === 'fileName' ? '<a href="view-source:' + e[T] + '" target="_blank">' + e[T] + '</a>'
412 								: e[T]);
413 			}catch (e) {}
414 
415 	// m += ' (' + arguments.callee.caller + ')';
416 	return m;
417 };
418 
419 
420 CeL.application.debug.log
421 .
422 /**
423  * get node description
424  * 
425  * @param node
426  *            HTML node
427  * @memberOf CeL.application.debug.log
428  */
429 node_description = function(node, flag) {
430 	if (typeof node === 'string')
431 		node = document.getElementById(node);
432 	if (!node)
433 		return;
434 
435 	var description = '';
436 
437 	if (node.id)
438 		description += '#' + node.id;
439 
440 	if (node.className)
441 		description += '.' + node.className;
442 
443 	if (node.tagName)
444 		description = '<' + node.tagName + description + '>';
445 
446 	if (!description && node.innerHTML) {
447 		description = node.innerHTML;
448 		if (description.length > 40)
449 			description = description.slice(0, 40);
450 		description = description.replace(/</g, '<');
451 	}
452 
453 	//	TODO: 對 Range object 之類的處理
454 	//	http://help.dottoro.com/ljxsqnoi.php
455 	return description || '(null description node: ' + library_namespace.is_type(node) + ')';
456 };
457 
458 
459 //預設以訊息框代替
460 CeL.application.debug.log
461 .
462 default_log_target =
463 	new Function('m',
464 			(typeof JSalert === 'function' ? 'JSalert'
465 					: typeof WScript === 'object' ? 'WScript.Echo' : 'alert')
466 			+ "(typeof m==='object'?'['+m.l+'] '+m.m:m);");
467 
468 
469 CeL.application.debug.log
470 .
471 /**
472  * get new extend instance
473  * @param	{String|object HTMLElement} [obj]	message area element or id
474  * @return	{Array} [ instance of this module, log function, warning function, error function ]
475  * @example
476  * 
477  * //	status logger
478  * var SL=new CeL.application.debug.log('log'),sl=SL[1],warn=SL[2],err=SL[3];
479  * sl(msg);
480  * sl(msg,clear);
481  * 
482  * //	general log
483  * function_set = new CeL.application.debug.log.extend('panel',{});
484  * // 1.
485  * function_set = new CeL.code.log.extend('panel',{});
486  * logger = function_set[1];
487  * // 2.
488  * log_only = (new CeL.code.log.extend('panel',{}))[1];
489  * 
490  * @_memberOf	CeL.application.debug.log
491  * @since	2009/8/24 20:15:31
492  */
493 extend = function(obj, className_set) {
494 	//CeL.Log=new CeL.code.log(function(m){var F=typeof JSalert==='function'?JSalert:typeof alert==='function'?alert:WScript.Echo;F(typeof m==='object'?'['+m.l+'] '+m.m:m);});
495 	/**
496 	 * new instance
497 	 * @type	CeL.application.debug.log
498 	 * @inner
499 	 * @ignore
500 	 */
501 	var o = new _// JSDT:_module_
502 			(obj || _.default_log_target, className_set);
503 
504 	// TODO: do not use arguments
505 	return [ o, function() {
506 		o.log.apply(o, arguments);
507 	}, function() {
508 		o.warn.apply(o, arguments);
509 	}, function() {
510 		o.err.apply(o, arguments);
511 	} ];
512 
513 };
514 
515 
516 /*
517 _.option_open=function(p){
518 
519 };
520 
521 _.option_file=function(p){
522 };
523 
524 _.option_folder=function(p){
525 };
526 */
527 
528 //	class constructor	---------------------------
529 
530 
531 CeL.application.debug.log
532 .prototype = {
533 
534 //	instance public interface	-------------------
535 
536 /**
537  * 當執行寫檔案或任何錯誤發生時之錯誤訊息。<br/>
538  * while error occurred.. should read only
539  * @name	CeL.application.debug.log.prototype.error_message
540  */
541 error_message : '',
542 
543 /**
544  * 超過這長度才 save。<=0 表示 autoflash,非數字則不紀錄。
545  * @name	CeL.application.debug.log.prototype.save_limit
546  * @type	Number
547  */
548 save_limit : 4000,
549 
550 /**
551  * 在 log 結束時執行,相當於 VB 中 DoEvent() 或 。
552  * @name	CeL.application.debug.log.prototype.do_event
553  */
554 do_event : library_namespace.DoNoting || null,
555 
556 
557 /**
558  * log 時使用之 tagName, 可用 div / span 等。若不設定會用 document.createTextNode
559  * @name	CeL.application.debug.log.prototype.log_tag
560  */
561 log_tag : 'div',
562 
563 
564 /**
565  * boolean or function(message, log level) return save or not
566  * 
567  * @name CeL.application.debug.log.prototype.save_log
568  * @type Boolean
569  */
570 save_log : false,
571 /**
572  * save log to this file path
573  * 
574  * @name CeL.application.debug.log.prototype.log_file
575  * @type Boolean
576  */
577 log_file : false,
578 /**
579  * auto save log. 若未設定,記得在 onunload 時 .save()
580  * 
581  * @name CeL.application.debug.log.prototype.flush
582  * @type Boolean
583  */
584 flush : false,
585 /**
586  * 在 save log 時 add date
587  * 
588  * @name CeL.application.debug.log.prototype.save_date
589  * @type Boolean
590  */
591 save_date : true,
592 /**
593  * 在 save log 時的換行
594  * 
595  * @name CeL.application.debug.log.prototype.save_new_line
596  * @type string
597  */
598 save_new_line : library_namespace.env.new_line || '\r\n',
599 /**
600  * 在 save log 時的 encoding
601  * 
602  * @name CeL.application.debug.log.prototype.log_encoding
603  */
604 log_encoding : -1,//TristateTrue
605 
606 
607 /**
608  * 自動捲動
609  * 
610  * @name CeL.application.debug.log.prototype.auto_scroll
611  * @type Boolean
612  */
613 auto_scroll : true,
614 /**
615  * 沒有內容時自動隱藏
616  * 
617  * @deprecated TODO
618  * @name CeL.application.debug.log.prototype.auto_hide
619  * @type Boolean
620  */
621 auto_hide : false,
622 
623 /**
624  * 等待多久才顯示 log。若為 0 則直接顯示。<br/>
625  * (WScript 沒有 setTimeout)
626  * @name	CeL.application.debug.log.prototype.interval
627  */
628 interval : typeof setTimeout === 'undefined' ? 0 : 1,
629 
630 /**
631  * log function (no delay)
632  * @name	CeL.application.debug.log.prototype.do_log
633  */
634 do_log : function(level) {
635 	// if(p[this.id].th)clearTimeout(p[this.id].th);
636 
637 	// reset timeout handle
638 	p[this.id].th = 0;
639 
640 	w(this.id);
641 },
642 
643 /**
644  * class instance 預設作 log 之 function
645  * @param {String} m	message
646  * @param clean	clean message area
647  * @param level	log level
648  * @return
649  * @name	CeL.application.debug.log.prototype.log
650  */
651 log : function(msg, clean, level) {
652 	var t = this, _p = p[t.id];
653 	//var msg_head=(arguments.callee.caller+'').match(/function\s([^\(]+)/);if(msg_head)msg_head=msg_head[1]+' ';
654 	s(msg, t.id, level);
655 
656 	// window.status = msg;
657 	if (level)
658 		msg = new log_data(msg, level);
659 
660 	if (clean)
661 		// clean log next time
662 		_p.clean = 1, _p.buf = [ msg ];
663 	else
664 		_p.buf.push(msg);
665 
666 	if (!t.interval)
667 		t.do_log();
668 	else if (!_p.th)
669 		if (typeof window.setTimeout === 'undefined')
670 			t.interval = 0, t.do_log();
671 		else
672 			// _p.th=setTimeout(cn+'.do_log('+t.id+');',t.interval);
673 			_p.th = window.setTimeout(function() {
674 				_.do_log(t.id);
675 			}, t.interval);
676 
677 	if (t.do_event)
678 		t.do_event();
679 },
680 
681 /*
682 TODO:
683 other methods: INFO,DEBUG,WARNING,ERROR,FATAL,UNKNOWN
684 */
685 
686 /**
687  * save message
688  * @name	CeL.application.debug.log.prototype.save
689  */
690 save : function() {
691 	s('', this.id, 1/* force */);
692 },
693 
694 //	** important ** 這邊不能作 object 之 initialization,否則因為 object 只會 copy reference,因此 new 時東西會一樣。initialization 得在 _() 中作!
695 //className_set:{},
696 
697 /**
698  * log a warning
699  * @name	CeL.application.debug.log.prototype.warn
700  */
701 warn : function(m, clean) {
702 	this.log(m, clean, 'warn');
703 },
704 
705 /**
706  * deal with error message
707  * @name	CeL.application.debug.log.prototype.err
708  */
709 err : function err(e, clean) {
710 	var caller = '';
711 	try {
712 		// TODO: do not use .caller
713 		caller = '' + err.caller;
714 		if (caller.indexOf('.err.apply(') !== -1)
715 			// ** 判斷 call from _.extend. 應該避免!
716 			caller = caller.caller;
717 	} catch (e) {
718 		// TODO: handle exception
719 	}
720 
721 	this.log(_.get_error_message(e, this.save_new_line,
722 			caller), clean, 'err');
723 },
724 
725 
726 /**
727  * 設定寫入到哪<br/>set log board for each instance (document object)
728  * @name	CeL.application.debug.log.prototype.set_board
729  */
730 set_board : function(o) {
731 	var _t = this, _p = p[_t.id];
732 	if (o)
733 		if (typeof o === 'function')
734 			_p.do_function = o;
735 
736 		else {
737 			if (typeof o !== 'object'
738 				&& typeof document === 'object')
739 				o = document.getElementById(o);
740 			if (o
741 					// TODO
742 					// && library_namespace.is_HTML_obj(o)
743 				) {
744 				_p.board = o;
745 				if (_t = _t.className_set.panel)
746 					o.className += _t;
747 				delete _p.do_function;
748 			}
749 		}
750 
751 	return _p.board;
752 },
753 
754 /**
755  * 獲取當前 buffer 中的 log
756  * @name	CeL.application.debug.log.prototype.get_log
757  */
758 get_log : function() {
759 	return p[this.id].lbuf;
760 },
761 
762 /**
763  * show/hide log board
764  * @name	CeL.application.debug.log.prototype.toggle
765  */
766 toggle : function(s) {
767 	var _s = p[this.id].board.style;
768 	if (_s) {
769 		if (typeof s === 'undefined')
770 			s = _s.display === 'none';
771 		return _s.display = s ? 'block' : 'none';
772 	}
773 },
774 
775 /**
776  * clear log board
777  * @name	CeL.application.debug.log.prototype.clear_board
778  */
779 clear_board : function(b) {
780 	b.innerHTML = '';
781 },
782 
783 /**
784  * 清除全部訊息 clear message
785  * @name	CeL.application.debug.log.prototype.clear
786  */
787 clear : function() {
788 	var _p = p[this.id];
789 	if (_p.board)
790 		this.clear_board(_p.board);
791 	_p.lbuf = [];
792 }
793 
794 };
795 
796 /**
797  * 不 extend 的 member.
798  * '*': 完全不 extend.
799  * this: 連 module 本身都不 extend 到 library name-space 下.
800  * @ignore
801  */
802 CeL.application.debug.log
803 .no_extend = 'this,do_log,extend';
804 
805 return (
806 	CeL.application.debug.log
807 );
808 };
809 
810 //	===================================================
811 
812 
813 //	為 modele log 所作的初始化工作
814 
815 /**
816  * modele namespace
817  * @type	CeL.application.debug.log
818  * @inner
819  * @ignore
820  */
821 var ns = CeL.setup_module(module_name, code_for_including);
822 
823 //WScript.Echo(n.extend);
824 
825 //code_for_including[generateCode.dLK]='*var Debug={log:code_for_including()};';
826 
827 CeL.include_module_resource('log.css', module_name);
828 
829 //	為本 library 用
830 if (!CeL.Log) {
831 	var o = ns.extend(), i,
832 		l = {
833 			/*
834 			 * WHITE SMILING FACE (U+263A).
835 			 * http://decodeunicode.org/en/u+263a
836 			 * http://wiki.livedoor.jp/qvarie/
837 			 */
838 			'log' : '☺',
839 			/*
840 			 * U+26A1 HIGH VOLTAGE SIGN
841 			 */
842 			'em' : '⚡',
843 			/*
844 			 * WARNING SIGN (U+26A0).
845 			 */
846 			'warn' : '⚠',
847 			/*
848 			 * U+2620 SKULL AND CROSSBONES
849 			 */
850 			'err' : '☠',
851 			/*
852 			 * U+2689 BLACK CIRCLE WITH TWO WHITE DOTS
853 			 */
854 			'debug' : '⚉'
855 		},
856 		t = '<img class="debug_icon" src="' + CeL.get_module_path(module_name, '') + 'icon/';
857 
858 	// override CeL.log
859 	CeL.Log = o[0];
860 	CeL.Log.className_set.em = 'debug_em';
861 	CeL.Log.className_set.debug = 'debug_debug';
862 
863 	for(i in l)
864 		CeL.Log.message_prefix[i] = t + i + '.png" alt="[' + l[i]
865 			+ ']" title="' + l[i] + ' ' + i + '"/> ';
866 
867 
868 	l = CeL.log && CeL.log.buffer;
869 
870 	CeL.log = o[1];
871 	CeL.warn = o[2];
872 	CeL.err = o[3];
873 	CeL.em = function(msg, clean) {
874 		CeL.Log.log.call(CeL.Log, msg, clean, 'em');
875 	};
876 	CeL.debug = function(msg, level, caller, clean) {
877 		//alert(CeL.is_debug() + ',' + l + '(' + (l === undefined) + '),' + msg);
878 		if (CeL.is_debug(level)){
879 			if(!caller)
880 				try {
881 					// TODO: do not use arguments
882 					caller = CeL.get_function_name(arguments.callee.caller);
883 				} catch (e) {
884 				}
885 
886 			CeL.Log.log.call(
887 					CeL.Log,
888 					caller ?
889 							'<span class="debug_caller">'
890 							+ caller//(caller.charAt(0) === '.' ? CeL.Class + caller : caller)
891 							+ '</span>: ' + msg
892 						: msg
893 					, clean, 'debug'
894 			);
895 		}
896 	};
897 
898 	if (l)
899 		for (i in l)
900 			CeL.debug('(before loading ' + module_name + ') ' + l[i]);
901 }
902 
903 })();
904 
905