/**
* debugData
*
* Pass me a data structure {} and I'll output all the key/value pairs - recursively
*
* @example var HTML = debugData( oElem.style, "Element.style", { keys: "top,left,width,height", recurse: true, sort: true, display: true, returnHTML: true });
*
* @param Object o_Data A JSON-style data structure
* @param String s_Title Title for dialog (optional)
* @param Hash options Pass additional options in a hash
*/
function debugData (o_Data, s_Title, options) {
options = options || {};
var
str=(s_Title||s_Title==='' ? s_Title : 'DATA')
, dType=$.type(o_Data)
// maintain backward compatibility with OLD 'recurseData' param
, recurse=($.type(options)==='boolean' ? options : options.recurse !==false)
, keys=(options.keys?','+options.keys+',':false)
, display=options.display !==false
, html=options.returnHTML !==false
, sort=!!options.sort
, prefix=options.indent ? ' ' : ''
, D=[], i=0 // Array to hold data, i=counter
, hasSubKeys = false
, k, t, skip, x, type // loop vars
;
if (dType!=='object' && dType!=='array') {
if (options.display) alert( (s_Title || 'debugData') +': '+ o_Data );
return o_Data;
}
if (dType==='object' && $.isPlainObject(o_Data))
dType='hash';
if (o_Data.jquery) {
str=s_Title+'jQuery Collection ('+ o_Data.length +')\n context="'+ o_Data.context +'"';
}
else if (o_Data.nodeName) {
str=s_Title+o_Data.tagName;
var id = o_Data.id, cls=o_Data.className, src=o_Data.src, hrf=o_Data.href;
if (id) str+='\n id="'+ id+'"';
if (cls) str+='\n class="'+ cls+'"';
if (src) str+='\n src="'+ src+'"';
if (hrf) str+='\n href="'+ hrf+'"';
}
else {
parse(o_Data,prefix,dType); // recursive parsing
if (sort && !hasSubKeys) D.sort(); // sort by keyName - but NOT if has subKeys!
if (str) str += '\n***'+ '****************************'.substr(0,str.length) +'\n';
str += D.join('\n'); // add line-breaks
}
if (display) alert(str); // display data
if (html) str=str.replace(/\n/g, '
').replace(/ /g, ' '); // format as HTML
return str;
function parse ( data, prefix, parentType ) {
var first = true;
try {
$.each( data, function (key, val) {
skip = (keys && keys.indexOf(','+key+',') === -1);
type = $.type(val);
if (type==='object' && $.isPlainObject(val))
type = 'hash';
k = prefix + (first ? ' ' : ', ');
first = false;
if (parentType!=='array') // no key-names for array items
k += key+': '; // NOT an array
if (type==="date" || type==="regexp") {
val = val.toString();
type = "string";
}
if (type==="string") { // STRING
if (!skip) D[i++] = k +'"'+ val +'"';
}
// NULL, UNDEFINED, NUMBER or BOOLEAN
else if (/^(null|undefined|number|boolean)/.test(type)) {
if (!skip) D[i++] = k + val;
}
else if (type==="function") { // FUNCTION
if (!skip) D[i++] = k +'function()';
}
else if (type==="array") { // ARRAY
if (!skip) {
D[i++] = k +'[';
parse( val, prefix+' ',type); // RECURSE
D[i++] = prefix +' ]';
}
}
else if (val.jquery) { // JQUERY OBJECT
if (!skip) D[i++] = k +'jQuery ('+ val.length +') context="'+ val.context +'"';
}
else if (val.nodeName) { // DOM ELEMENT
var id = val.id, cls=val.className, src=val.src, hrf=val.href;
if (skip) D[i++] = k +' '+
id ? 'id="'+ id+'"' :
src ? 'src="'+ src+'"' :
hrf ? 'href="'+ hrf+'"' :
cls ? 'class="'+cls+'"' :
'';
}
else if (type==="hash") { // JSON
if (!recurse || $.isEmptyObject(val)) { // show an empty hash
if (!skip) D[i++] = k +'{ }';
}
else { // recurse into JSON hash - indent output
D[i++] = k +'{';
parse( val, prefix+' ',type); // RECURSE
D[i++] = prefix +' }';
}
}
else { // OBJECT
if (!skip) D[i++] = k +'OBJECT'; // NOT a hash
}
});
} catch (e) {}
}
};
function debugStackTrace (s_Title, options) {
var
callstack = []
, isCallstackPopulated = false
;
try {
i.dont.exist += 0; // doesn't exist- that's the point
} catch(e) {
if (e.stack) { // Firefox
var lines = e.stack.split('\n');
for (var i=0, len=lines.length; i')
.html( content.replace(/\n/g, '
').replace(/ /g, ' ') ) // format as HTML
.css( options.css )
;
};