/**
* @name CeL function for debug
* @fileoverview 本檔案包含了 debug 用的 functions。
* @since
* @see http://code.google.com/apis/ajax/playground/
*/
'use strict';
// --------------------------------------------------------------------------------------------
// 不採用 if 陳述式,可以避免 Eclipse JSDoc 與 format 多縮排一層。
typeof CeL === 'function' && CeL.run({
// module name
name : 'application.debug',
require : 'data.code.compatibility.|interact.DOM.',
// 設定不匯出的子函式。
// 'log': 為預防覆寫基底之 log 而加。
no_extend : 'this,log',
// 為了方便格式化程式碼,因此將 module 函式主體另外抽出。
code : module_code
});
function module_code(library_namespace) {
// JSalert[generateCode.dLK]='getScriptName';
// ,*var ScriptName=getScriptName();
/**
* 顯示訊息視窗
* alert() 改用VBScript的MsgBox可產生更多效果,但NS不支援的樣子。
*
* @param message
* message or object
* @param {Number}
* [wait] the maximum length of time (in seconds) you want the
* pop-up message box displayed.
* @param {String}
* [title] title of the pop-up message box.
* @param {Number}
* [type] type of buttons and icons you want in the pop-up
* message box.
* @return {Integer} number of the button the user clicked to dismiss the
* message box.
* @requires CeL.get_script_name
* @see Popup
* Method
* @_memberOf _module_
*/
function JSalert(message, wait, title, type) {
var _f = arguments.callee;
if (typeof _f.cmd === 'undefined') // 控制是否彈跳出視窗
_f.cmd = typeof WScript === 'object'
&& /cscript\.exe$/i.test(WScript.FullName);
// if(!message)message+='';
// if(typeof message==='undefined')message='';else
// if(!message)message+='';
// 有時傳入如message==null會造成error
// WScript.Echo()會視情況:視窗執行時彈跳出視窗,cmd執行時直接顯示。但需要用cscript執行時才有效果。
// http://www.microsoft.com/technet/scriptcenter/guide/sas_wsh_mokz.mspx
// 可以用 WScript.Echo(t1,t2,..),中間會以' '間隔
if (_f.cmd && argument.length < 2)
return WScript.Echo(message);
if (!title &&
// typeof getScriptName === 'function'
this.get_script_name)
title = getScriptName();
if (isNaN(type))// typeof type!=='number'
type = 64;
if (false && typeof WshShell != 'object')
if (typeof WScript === 'object')
WshShell = WScript.CreateObject("WScript.Shell");
else
return undefined;
if (this.WshShell !== 'object')
if (typeof WScript === 'object')
this.WshShell = WScript.CreateObject("WScript.Shell");
else
return undefined;
return this.WshShell.Popup(
// ''+message: 會出現 typeof message==='object' 卻不能顯示的
'' + message, wait, title, type);
}
// ---------------------------------------------------------------------//
// popup object Error(錯誤)
// popErr[generateCode.dLK]='JSalert,setTool,parse_Function';
// error object, title, additional text(etc. function name)
function popErr(e, t, f) {
var T = typeof e;
if (false)
alert((T == 'object') + ',' + (e.constructor) + ',' + (Error) + ','
+ (e instanceof Error));
// 這裡e instanceof Error若是T=='object'&&e.constructor==Error有時不能達到效果!
// use: for(i in e)
T = e instanceof Error ? 'Error '
+ (e.number & 0xFFFF)
+ (e.name ? ' [' + e.name + ']' : '')
+ ' (facility code '
+ (e.number >> 16 & 0x1FFF)
+ '):\n'
+ e.description
+ (!e.message || e.message === e.description ? '' : '\n\n'
+ e.message) : !e || T === 'string' ? e : '(' + T + ')'
+ e;
f = f ? ('' + f).replace(/\0/g, '\\0') + '\n\n' + T : T;
// .caller只在執行期間有效。_function_self_.caller可用 arguments.callee.caller
// 代替,卻不能用arguments.caller
// arguments.callee.caller 被棄用了。
// http://www.opera.com/docs/specs/js/ecma/
// http://bytes.com/forum/thread761008.html
// http://www.javaeye.com/post/602661
// http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/cd3d6d6abcdd048b
if (typeof WshShell === 'object')
WshShell.Popup(f, 0, t || 'Error '
//
+ (arguments.callee.caller === null ? 'from the top level'
//
: 'on ' + (typeof parse_Function == 'function'
//
? parse_Function(arguments.callee.caller).funcName
//
: 'function')) + ' of ' + ScriptName, 16);
else
alert(f);
return T;
}
// ---------------------------------------------------------------------//
var show_value_max_length = 80, toString = Object.prototype.toString;
function show_value_get_type(value) {
var type = toString.call(value), _type;
if (type === '[object Object]')
try {
// test DOM.
if (/^\[[^]]+\]$/.test(_type = '' + value))
return _type;
} catch (e) {
}
return type || typeof value;
}
// show value[key]
function show_value_single(key, value, filter, key_is_name) {
var name, value_String, no_more, nodes = [];
library_namespace.debug('add name', 3, 'show_value_single');
if (key_is_name && key === undefined)
name = '(null name)';
else
try {
name = '' + key;
nodes.push({
span : name || '(null name)',
S : name ? 'color:#a93;' : 'color:#888;'
}, ': ');
if (name)
name = '[' + name + ']';
} catch (e) {
// no .toString()?
// e.g., Object.create(null)
name = '(error name)';
nodes.push({
span : '(error to get valuable name: ' + e.message + ')',
S : 'color:#e32;'
}, ': ');
}
if (!key_is_name)
try {
value = value[key];
} catch (e) {
value_String = true;
nodes.push({
span : '(error to get value of ' + name + ': ' + e.message
+ ')',
S : 'color:#e32;'
});
}
if (!value_String)
if (value === undefined || value === null)
// 在 IE 中,typeof null, undefined === object。
nodes.push({
span : '(' + value + ')',
S : 'color:#888;'
});
else if (typeof (no_more = show_value.type_handler
.get(value_String = show_value_get_type(value))) !== 'function'
|| no_more(value, nodes)) {
library_namespace.debug('add type', 3, 'show_value_single');
if (no_more = value_String.match(/^\[object ([^]]+)\]$/))
no_more = (value_String = no_more[1]) in {
// 這幾種將作特殊處理。
Object : 1,
Array : 1,
Function : 1
} && !/^\s*function[\s(]/.test('' + value);
nodes.push({
span : value_String,
S : 'color:#6a3;'
});
try {
if (!isNaN(value.length))
nodes.push('[' + value.length + ']');
} catch (e) {
}
library_namespace.debug('add value', 3, 'show_value_single');
try {
// 為特殊值作特殊處理。
if (no_more) {
var is_Array = value_String === 'Array', val, full_listed;
value_String = is_Array ? '[ ' : '{ ';
for (key in value)
try {
if (Object.hasOwn(value, key)) {
if (!is_Array)
value_String += '' + key;
if ((val = '' + value[key]).length < 9) {
if (!is_Array)
value_String += ':';
value_String += val;
}
// value_String += '|';
value_String += ', ';
full_listed = true;
}
if (value_String.length >= show_value_max_length) {
value_String += ' .. ';
full_listed = false;
break;
}
} catch (e) {
}
prototype = null;
if (full_listed)
value_String = value_String.slice(0, -2);
value_String += (is_Array ? ' ]' : ' }');
// no_more = true;
} else
no_more = (value_String = '' + value).length < show_value_max_length;
key = (no_more ? value_String : value_String.slice(0,
show_value_max_length)).replace(/ 1
&& parent.lastChild.className === 'show_value_block') {
key = parent.lastChild.style;
// toggle
key.display = key.display === 'none' ? '' : 'none';
return;
}
try {
length = value && value.length;
} catch (e) {
library_namespace.warn('show_value_children: ' + e.message);
}
try {
proto = [];
for (key in value) {
if (length && (key === '0' || key === 0))
// 代表已經遍歷過。
length = 0;
if (!filter || filter.test(key))
(Object.hasOwn(value, key) ? nodes : proto).push({
div : show_value_single(key, value, filter),
S : 'margin-left:1em;'
});
}
if (library_namespace.is_RegExp(value))
// RegExp 有許多無法 enumerable 的 properties。
RegExp_properties.forEach(function(key) {
if (!filter || filter.test(key))
nodes.push({
div : show_value_single(key, value, filter),
S : 'margin-left:1em;'
});
});
} catch (e) {
library_namespace.warn('show_value_children: ' + e.message);
}
if (isNaN(length) || length > 0)
try {
// 處理 childNodes[] 之類。
for (key = 0; key < length || value[key] !== undefined; key++)
if (!filter || filter.test(key)) {
nodes.push({
div : show_value_single(key, value, filter),
S : 'margin-left:1em;'
});
}
} catch (e) {
library_namespace.warn('show_value_children: ' + e.message);
}
if (proto && proto.length > 0) {
nodes.push({
a : 'inherited:',
href : '#',
S : 'margin-left:1em;',
onclick : function() {
var style = this.nextSibling.style;
style.display = style.display === 'none' ? '' : 'none';
return false;
}
}, {
div : proto,
S : nodes.length > 0 ? 'display:none;' : ''
});
}
nodes = {
div : nodes.length > 0 ? nodes : '(no properties)',
C : 'show_value_block',
S : nodes.length > 0 ? '' : 'color:#888;'
};
library_namespace.new_node(nodes, [ parent, 2 ]);
// key = value = nodes = parent = proto = null;
}
var has_native_log = typeof console === 'object'
&& library_namespace.is_native_Function(console.log);
/**
* debug 用: Show contents of object/class.
*
* TODO: update, paging + real-time search
*
* @see 一些內建的物件,他的屬性可能會是[[DontEnum]],也就是不可列舉的,而自訂的物件在下一版的ECMA-262中,也可以這樣設定他的屬性。
*/
function show_value(object, name, filter) {
if (has_native_log) {
// if (name) console.log(name + ':');
// console.log(object);
return;
}
if (name === undefined && typeof object !== 'object'
&& typeof object !== 'function')
try {
name = '' + object;
} catch (e) {
}
library_namespace.log([ 'show_value: ',
show_value_single(name, object, filter, true) ]);
}
// function() return true: 繼續處理。
show_value.type_handler = new Map;
// show_value(1);
if (false)
show_value({
test_null : null,
test_undefined : undefined,
test_Boolean_true : true,
test_Boolean_false : false,
test_Number : 43.2,
test_String : 'a string',
test_Array : [ -34.3, 'a\\f', {
r : 4,
w : {
a : 5
}
} ],
test_Object : {
l : {
e : 3
},
r : 5
}
});
return [ JSalert, popErr, show_value ];
}