|
|
(20 intermediate revisions by 2 users not shown) |
Line 1: |
Line 1: |
| <pre>/*
| | This doc was moved to http://searchfox.org/mozilla-central/source/devtools/docs/backend/client-api.md |
| * Debugger API demo.
| |
| * Try it in Scratchpad with Environment -> Browser, using
| |
| * http://htmlpad.org/debugger/ as the current page.
| |
| */
| |
| let client;
| |
| let threadClient;
| |
| | |
| function startDebugger()
| |
| {
| |
| // Start the server.
| |
| if (!DebuggerServer.initialized) {
| |
| DebuggerServer.init();
| |
| DebuggerServer.addBrowserActors();
| |
| }
| |
| // Listen to an nsIPipe
| |
| let transport = DebuggerServer.connectPipe();
| |
| // For an nsIServerSocket we do this:
| |
| // DebuggerServer.openListener(aPort, aLocalOnly);
| |
| // ...and this at the client:
| |
| // let transport = debuggerSocketConnect(aHost, aPort);
| |
|
| |
| // Start the client.
| |
| client = new DebuggerClient(transport);
| |
| // Attach listeners for client events.
| |
| client.addListener("tabNavigated", onTab);
| |
| client.addListener("newScript", fooListener);
| |
| client.ready(function(aType, aTraits) {
| |
| // Now the client is conected to the server.
| |
| debugTab();
| |
| });
| |
| }
| |
| | |
| function shutdownDebugger()
| |
| {
| |
| client.close();
| |
| }
| |
| | |
| /**
| |
| * Start debugging the current tab.
| |
| */
| |
| function debugTab()
| |
| {
| |
| // Get the list of tabs to find the one to attach to.
| |
| client.listTabs(function(aResponse) {
| |
| // Find the active tab.
| |
| let tab = aResponse.tabs[aResponse.selected];
| |
| // Attach to the tab.
| |
| client.attachTab(tab.actor, function(aResponse, aTabClient) {
| |
| if (!aTabClient) return;
| |
| // Attach to the thread (context).
| |
| client.attachThread(aResponse.threadActor, function(aResponse, aThreadClient) {
| |
| if (!aThreadClient) return;
| |
| threadClient = aThreadClient;
| |
| // Attach listeners for thread events.
| |
| threadClient.addListener("paused", onPause);
| |
| threadClient.addListener("resumed", fooListener);
| |
| threadClient.addListener("detached", fooListener);
| |
| threadClient.addListener("framesadded", onFrames);
| |
| threadClient.addListener("framescleared", fooListener);
| |
| threadClient.addListener("scriptsadded", onScripts);
| |
| threadClient.addListener("scriptscleared", fooListener);
| |
| // Resume the thread.
| |
| threadClient.resume();
| |
| // Debugger is now ready and debuggee is running.
| |
| });
| |
| });
| |
| });
| |
| }
| |
| | |
| /**
| |
| * Handler for location changes.
| |
| */
| |
| function onTab()
| |
| {
| |
| // Detach from the previous thread.
| |
| client.activeThread.detach(function() {
| |
| // Detach from the previous tab.
| |
| client.activeTab.detach(function() {
| |
| // Start debugging the new tab.
| |
| debugTab();
| |
| });
| |
| });
| |
| }
| |
| | |
| /**
| |
| * Handler for entering pause state.
| |
| */
| |
| function onPause()
| |
| {
| |
| // Get the top 20 frames in the server's frame stack cache.
| |
| client.activeThread.fillFrames(20);
| |
| // Get the scripts loaded in the server's source script cache.
| |
| client.activeThread.fillScripts();
| |
| }
| |
| | |
| /**
| |
| * Handler for framesadded events.
| |
| */
| |
| function onFrames()
| |
| {
| |
| // Get the list of frames in the server.
| |
| for each (let frame in client.activeThread.cachedFrames) {
| |
| // frame is a Debugger.Frame grip.
| |
| dump("frame: " + frame.toSource() + "\n");
| |
| inspectFrame(frame);
| |
| }
| |
| }
| |
| | |
| /**
| |
| * Handler for scriptsadded events.
| |
| */
| |
| function onScripts()
| |
| {
| |
| // Get the list of scripts in the server.
| |
| for each (let script in client.activeThread.cachedScripts) {
| |
| // script is a Debugger.Script grip.
| |
| dump("script: " + script.toSource() + "\n");
| |
| }
| |
| | |
| // Resume execution, since this is the last thing going on in the paused
| |
| // state and there is no UI in this program. Wait a bit so that object
| |
| // inspection has a chance to finish.
| |
| setTimeout(function() {
| |
| threadClient.resume();
| |
| }, 1000);
| |
| }
| |
| | |
| /**
| |
| * Helper function to inspect the provided frame.
| |
| */
| |
| function inspectFrame(aFrame)
| |
| {
| |
| // Get the "this" object.
| |
| if (aFrame["this"]) {
| |
| getObjectProperties(aFrame["this"]);
| |
| }
| |
| // Add "arguments".
| |
| if (aFrame.arguments && aFrame.arguments.length > 0) {
| |
| // frame.arguments is a regular Array.
| |
| dump("frame.arguments: " + aFrame.arguments.toSource() + "\n");
| |
| // Add variables for every argument.
| |
| let objClient = client.activeThread.pauseGrip(aFrame.callee);
| |
| objClient.nameAndParameters(function(aResponse) {
| |
| for (let i = 0; i < aResponse.parameters.length; i++) {
| |
| let name = aResponse.parameters[i];
| |
| let value = aFrame.arguments[i];
| |
| if (typeof value == "object" && value.type == "object") {
| |
| getObjectProperties(value);
| |
| }
| |
| }
| |
| });
| |
| }
| |
| }
| |
| | |
| /** | |
| * Helper function that retrieves the specified object's properties.
| |
| */
| |
| function getObjectProperties(aObject)
| |
| {
| |
| let thisClient = client.activeThread.pauseGrip(aObject);
| |
| thisClient.prototypeAndProperties(function(aResponse) {
| |
| // Get prototype as a protocol-specified grip.
| |
| if (aResponse.prototype.type != "null") {
| |
| dump("__proto__: " + aResponse.prototype.toSource() + "\n");
| |
| }
| |
| // Get the rest of the object's own properties as protocol-specified grips.
| |
| for each (let prop in Object.keys(aResponse.ownProperties)) {
| |
| dump(prop + ": " + aResponse.ownProperties[prop].toSource() + "\n");
| |
| }
| |
| });
| |
| }
| |
| | |
| /**
| |
| * Generic event listener.
| |
| */
| |
| function fooListener(aEvent)
| |
| {
| |
| dump(aEvent + "\n");
| |
| }
| |
| | |
| // Run the program.
| |
| startDebugger();
| |
| // Execute the following line to stop the program.
| |
| //shutdownDebugger();
| |
| | |
| | |
| </pre>
| |
| <br>
| |