netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); const Cc = Components.classes; const Ci = Components.interfaces; const RETURN_CONTINUE = Ci.jsdIExecutionHook.RETURN_CONTINUE; const DebuggerService = Cc["@mozilla.org/js/jsd/debugger-service;1"]; var jsd = Components.classes['@mozilla.org/js/jsd/debugger-service;1'] .getService(Ci.jsdIDebuggerService); var jsdOnAtStart = false; function setupJSD(test) { netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); jsdOnAtStart = jsd.isOn; if (jsdOnAtStart) { runTest(); } else { jsd.asyncOn({ onDebuggerActivated: function() { runTest(); } }); } } // Ugly workaround: when you turn the debugger on, it will only see scripts // compiled after that point. And it may be turned on asynchronously. So // we put the debugged code into a separate script that gets loaded after // the debugger is on. function loadScript(url, element) { var script = document.createElement('script'); script.type = 'text/javascript'; script.src = url; script.defer = false; element.appendChild(script); } function findScriptByFunction(name) { var script; jsd.enumerateScripts({ enumerateScript: function(script_) { if (script_.functionName === name) { script = script_; } } }); if (typeof(script) === "undefined") { throw("Cannot find function named '" + name + "'"); } return script; } // Pass in a JSD script function breakOnAllLines(script) { // Map each line to a PC, and collect that set of PCs (removing // duplicates.) var pcs = {}; for (i = 0; i < script.lineExtent; i++) { var jsdLine = script.baseLineNumber + i; var pc = script.lineToPc(jsdLine, Ci.jsdIScript.PCMAP_SOURCETEXT); pcs[pc] = 1; } // Set a breakpoint on each of those PCs. for (pc in pcs) { try { script.setBreakpoint(pc); } catch(e) { alert("Error setting breakpoint: " + e); } } } // Set a breakpoint on a script, where lineno is relative to the beginning // of the script (NOT the absolute line number within the file). function breakOnLine(script, lineno) { breakOnAbsoluteLine(script, script.baseLineNumber + lineno); } function breakOnAbsoluteLine(script, lineno) { var pc = script.lineToPc(lineno, Ci.jsdIScript.PCMAP_SOURCETEXT); script.setBreakpoint(pc); } function loadPage(page) { var url; if (page.match(/^\w+:/)) { // Full URI, so just use it url = page; } else { // Treat as relative to previous page url = document.location.href.replace(/\/[^\/]*$/, "/" + page); } dump("Switching to URL " + url + "\n"); gURLBar.value = url; gURLBar.handleCommand(); } function breakpointObserver(lines, interesting, callback) { jsd.breakpointHook = { onExecute: function(frame, type, rv) { breakpoints_hit.push(frame.line); if (frame.line in interesting) { return callback(frame, type, breakpoints_hit); } else { return RETURN_CONTINUE; } } }; } function dumpStack(frame, msg) { netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); dump(msg + ":\n"); while(frame) { var callee = frame.callee; if (callee !== null) callee = callee.jsClassName; dump(" " + frame.script.fileName + ":" + frame.line + " func=" + frame.script.functionName + " ffunc=" + frame.functionName + " callee=" + callee + " pc=" + frame.pc + "\n"); frame = frame.callingFrame; } }