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