commit 3b8ce8e411e787da760248df7d9d88c5a44c2440
parent 0b3b296e28305bb4a8e73ab3d1ba6ebdde4c7411
Author: Dan Stillman <dstillman@zotero.org>
Date: Sat, 27 Dec 2014 14:11:24 -0500
Merge pull request #599 from aurimasv/varDump
varDump update
Diffstat:
3 files changed, 109 insertions(+), 106 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;
},
/**
diff --git a/chrome/content/zotero/xpcom/zotero.js b/chrome/content/zotero/xpcom/zotero.js
@@ -46,7 +46,6 @@ Components.utils.import("resource://gre/modules/Services.jsm");
this.logError = logError;
this.getErrors = getErrors;
this.getSystemInfo = getSystemInfo;
- this.safeDebug = safeDebug;
this.getString = getString;
this.localeJoin = localeJoin;
this.setFontSize = setFontSize;
@@ -1398,22 +1397,6 @@ Components.utils.import("resource://gre/modules/Services.jsm");
AddonManager.getAllAddons(onHaveInstalledAddons);
}
-
- function safeDebug(obj){
- for (var i in obj){
- try {
- Zotero.debug(i + ': ' + obj[i]);
- }
- catch (e){
- try {
- Zotero.debug(i + ': ERROR');
- }
- catch (e){}
- }
- }
- }
-
-
function getString(name, params){
try {
if (params != undefined){