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