www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | Submodules | README | LICENSE

commit 20a50d1aaa7a54fe2adefdd52191a088d60a999e
parent 0b3b296e28305bb4a8e73ab3d1ba6ebdde4c7411
Author: Aurimas Vinckevicius <aurimas.dev@gmail.com>
Date:   Mon, 22 Dec 2014 23:43:46 -0600

Refactor Zotero.Utilities.varDump. Add handling for Error and XPCOM objects

Diffstat:
Mchrome/content/zotero/xpcom/debug.js | 17-----------------
Mchrome/content/zotero/xpcom/utilities.js | 181+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
2 files changed, 109 insertions(+), 89 deletions(-)

diff --git a/chrome/content/zotero/xpcom/debug.js b/chrome/content/zotero/xpcom/debug.js @@ -46,23 +46,6 @@ Zotero.Debug = new function () { return; } - // Properly display thrown Error objects - if (message && message.constructor) { - switch (message.constructor.name) { - case 'Error': - case 'EvalError': - case 'RangeError': - case 'ReferenceError': - case 'SyntaxError': - case 'TypeError': - case 'URIError': - message = "'message' => \"" + message.message + "\"\n" - + Zotero.Utilities.varDump(message) + "\n" - + message.stack; - break; - } - } - if (typeof message != 'string') { message = Zotero.Utilities.varDump(message); } diff --git a/chrome/content/zotero/xpcom/utilities.js b/chrome/content/zotero/xpcom/utilities.js @@ -1159,96 +1159,133 @@ Zotero.Utilities = { * * Adapted from http://binnyva.blogspot.com/2005/10/dump-function-javascript-equivalent-of.html */ - "varDump":function(arr,level,maxLevel,parentObjects,path) { - var dumped_text = ""; - if (level === undefined){ + "varDump": function(obj,level,maxLevel,parentObjects,path) { + // Simple dump + var type = typeof obj; + if (type == 'number' || type == 'undefined' || type == 'boolean' || obj === null) { + if (!level) { + // When dumping these directly, make sure to distinguish them from regular + // strings as output by Zotero.debug (i.e. no quotes) + return '===>' + obj + '<=== (' + type + ')'; + } + else { + return '' + obj; + } + } + else if (type == 'string') { + return JSON.stringify(obj); + } + else if (type == 'function') { + var funcStr = ('' + obj).trim(); + if (!level) { + // Dump function contents as well if only dumping function + return funcStr; + } + + // Display [native code] label for native functions, but make it one line + if (/^[^{]+{\s*\[native code\]\s*}$/i.test(funcStr)) { + return funcStr.replace(/\s*(\[native code\])\s*/i, ' $1 '); + } + + // For non-native functions, display an elipsis + return ('' + obj).replace(/{[\s\S]*}/, '{...}'); + } + else if (type != 'object') { + return '<<Unknown type: ' + type + '>> ' + obj; + } + + // More complex dump with indentation for objects + if (level === undefined) { level = 0; } - + if (maxLevel === undefined) { maxLevel = 4; } - + + var objType = Object.prototype.toString.call(obj); + + if (level > maxLevel) { + return objType + " <<Maximum depth reached>>"; + } + // The padding given at the beginning of the line. var level_padding = ""; - for (var j=0;j<level+1;j++){ + for (var j=0; j<level+1; j++) { level_padding += " "; } - - if (level > maxLevel){ - return dumped_text + level_padding + "<<Maximum depth reached>>...\n"; + + //Special handling for Error + var isError = obj instanceof Error; + if (!isError && obj.constructor) { + switch (obj.constructor.name) { + case 'Error': + case 'EvalError': + case 'RangeError': + case 'ReferenceError': + case 'SyntaxError': + case 'TypeError': + case 'URIError': + isError = true; + } + } + if (isError) { + return (obj.constructor.name ? obj.constructor.name : 'Error') + ': ' + + (obj.message ? ('' + obj.message).replace(/^/gm, level_padding).trim() : '') + + '\n' + level_padding + "===== Stack Trace =====\n" + + (obj.stack ? obj.stack.trim().replace(/^(?=.)/gm, level_padding) : '') + + '\n' + level_padding + "======================="; + } + + // Only dump single level for nsIDOMNode objects (including document) + if (Zotero.isFx && !Zotero.isBookmarklet + && obj instanceof Components.interfaces.nsIDOMNode + ) { + level = maxLevel; + } + + // Recursion checking + if(!parentObjects) { + parentObjects = [obj]; + path = ['ROOT']; } - if (typeof(arr) == 'object') { // Array/Hashes/Objects - var isRequest = Zotero.isFx && !Zotero.isBookmarklet - && arr instanceof Components.interfaces.nsIRequest; + var isArray = objType == '[object Array]' + var dumpedText = isArray ? '[' : objType + ' {'; + for (var prop in obj) { + dumpedText += '\n' + level_padding + JSON.stringify(prop) + ": "; - //array for checking recursion - //initialise at first itteration - if(!parentObjects) { - parentObjects = [arr]; - path = ['ROOT']; + try { + var value = obj[prop]; + } catch(e) { + dumpedText += "<<Access Denied>>"; + continue; } - - for (var item in arr) { - try { - // Don't display nsIRequest.name, which can contain password - if (isRequest && item == 'name') { - dumped_text += level_padding + "'" + item + "' => <<Skipped>>\n"; - continue; - } - - var value = arr[item]; - } catch(e) { - dumped_text += level_padding + "'" + item + "' => <<Access Denied>>\n"; + + // Check for recursion + if (typeof(value) == 'object') { + var i = parentObjects.indexOf(value); + if(i != -1) { + var parentName = path.slice(0,i+1).join('->'); + dumpedText += "<<Reference to parent object " + parentName + " >>"; continue; } - - if (typeof(value) == 'object') { // If it is an array - //check for recursion - var i = parentObjects.indexOf(value); - if(i != -1) { - var parentName = path.slice(0,i+1).join('->'); - dumped_text += level_padding + "'" + item + "' => <<Reference to parent object " + parentName + " >>\n"; - continue; - } - - var openBrace = '{', closeBrace = '}'; - var type = Object.prototype.toString.call(value); - if(type == '[object Array]') { - openBrace = '['; - closeBrace = ']'; - } - - dumped_text += level_padding + "'" + item + "' => " + type + ' ' + openBrace; - //only recurse if there's anything in the object, purely cosmetical - try { - for(var i in value) { - dumped_text += "\n" + Zotero.Utilities.varDump(value,level+1,maxLevel,parentObjects.concat([value]),path.concat([item])) + level_padding; - break; - } - } catch(e) { - dumped_text += "<<Error processing object:\n" + e + ">>\n"; - } - dumped_text += closeBrace + "\n"; - } - else { - if (typeof value == 'function'){ - dumped_text += level_padding + "'" + item + "' => function(...){...} \n"; - } - else if (typeof value == 'number') { - dumped_text += level_padding + "'" + item + "' => " + value + "\n"; - } - else { - dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n"; - } - } + } + + try { + dumpedText += Zotero.Utilities.varDump(value,level+1,maxLevel,parentObjects.concat([value]),path.concat([prop])); + } catch(e) { + dumpedText += "<<Error processing property: " + e.message + " (" + value + ")>>"; } } - else { // Stings/Chars/Numbers etc. - dumped_text = "===>"+arr+"<===("+typeof(arr)+")"; + + var lastChar = dumpedText.charAt(dumpedText.length - 1); + if (lastChar != '[' && lastChar != '{') { + dumpedText += '\n' + level_padding.substr(4); } - return dumped_text; + dumpedText += isArray ? ']' : '}'; + + return dumpedText; }, /**