/** * @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 ]; }