Bug 859372 - Refactor script.js; r=past
authorEddy Bruel <ejpbruel@mozilla.com>
Tue, 29 Apr 2014 17:52:44 +0200
changeset 181233 f52ced52f369aec791f398051ac4b776ca9cdee1
parent 181232 ac59b6185d615b035601dde5287b7818973d7ae2
child 181234 24c0d935bc4b41721e190b40355a71f3e622501a
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
reviewerspast
bugs859372
milestone32.0a1
Bug 859372 - Refactor script.js; r=past
browser/devtools/debugger/debugger-toolbar.js
browser/devtools/debugger/test/head.js
toolkit/devtools/server/actors/script.js
toolkit/devtools/server/actors/webbrowser.js
toolkit/devtools/server/actors/webconsole.js
toolkit/devtools/server/main.js
toolkit/devtools/server/tests/unit/head_dbg.js
toolkit/devtools/server/tests/unit/test_breakpointstore.js
toolkit/devtools/server/tests/unit/test_longstringactor.js
toolkit/devtools/server/tests/unit/testactors.js
--- a/browser/devtools/debugger/debugger-toolbar.js
+++ b/browser/devtools/debugger/debugger-toolbar.js
@@ -504,22 +504,23 @@ StackFramesView.prototype = Heritage.ext
   /**
    * The select listener for the stackframes container.
    */
   _onSelect: function(e) {
     let stackframeItem = this.selectedItem;
     if (stackframeItem) {
       // The container is not empty and an actual item was selected.
       let depth = stackframeItem.attachment.depth;
-      DebuggerController.StackFrames.selectFrame(depth);
 
       // Mirror the selected item in the classic list.
       this.suppressSelectionEvents = true;
       this._mirror.selectedItem = e => e.attachment.depth == depth;
       this.suppressSelectionEvents = false;
+
+      DebuggerController.StackFrames.selectFrame(depth);
     }
   },
 
   /**
    * The scroll listener for the stackframes container.
    */
   _onScroll: function() {
     // Update the stackframes container only if we have to.
--- a/browser/devtools/debugger/test/head.js
+++ b/browser/devtools/debugger/test/head.js
@@ -744,20 +744,21 @@ function openVarPopup(aPanel, aCoords, a
   let editor = aPanel.panelWin.DebuggerView.editor;
   let bubble = aPanel.panelWin.DebuggerView.VariableBubble;
   let tooltip = bubble._tooltip.panel;
 
   let popupShown = once(tooltip, "popupshown");
   let fetchedProperties = aWaitForFetchedProperties
     ? waitForDebuggerEvents(aPanel, events.FETCHED_BUBBLE_PROPERTIES)
     : promise.resolve(null);
+  let updatedFrame = waitForDebuggerEvents(aPanel, events.FETCHED_SCOPES);
 
   let { left, top } = editor.getCoordsFromPosition(aCoords);
   bubble._findIdentifier(left, top);
-  return promise.all([popupShown, fetchedProperties]).then(waitForTick);
+  return promise.all([popupShown, fetchedProperties, updatedFrame]).then(waitForTick);
 }
 
 // Simulates the mouse hovering a variable in the debugger
 // Takes in account the position of the cursor in the text, if the text is
 // selected and if a button is currently pushed (aButtonPushed > 0).
 // The function returns a promise which returns true if the popup opened or
 // false if it didn't
 function intendOpenVarPopup(aPanel, aPosition, aButtonPushed) {
--- a/toolkit/devtools/server/actors/script.js
+++ b/toolkit/devtools/server/actors/script.js
@@ -1,16 +1,28 @@
 /* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; js-indent-level: 2; -*- */
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
+const Debugger = require("Debugger");
+const Services = require("Services");
+const { Cc, Ci, Cu, components } = require("chrome");
+const { ActorPool } = require("devtools/server/actors/common");
+const { DebuggerServer } = require("devtools/server/main");
+const DevToolsUtils = require("devtools/toolkit/DevToolsUtils");
+const { dbg_assert, dumpn } = DevToolsUtils;
+const { SourceMapConsumer, SourceMapGenerator } = require("source-map");
+const { all, defer, resolve } = promise;
+
+Cu.import("resource://gre/modules/NetUtil.jsm");
+
 let B2G_ID = "{3c2e2abc-06d4-11e1-ac3b-374f68613e61}";
 
 let TYPED_ARRAY_CLASSES = ["Uint8Array", "Uint8ClampedArray", "Uint16Array",
       "Uint32Array", "Int8Array", "Int16Array", "Int32Array", "Float32Array",
       "Float64Array"];
 
 // Number of items to preview in objects, arrays, maps, sets, lists,
 // collections, etc.
@@ -33,17 +45,17 @@ function mapURIToAddonID(uri, id) {
     addonManager = Cc["@mozilla.org/addons/integration;1"].
                    getService(Ci.amIAddonManager);
   }
 
   try {
     return addonManager.mapURIToAddonID(uri, id);
   }
   catch (e) {
-    DevtoolsUtils.reportException("mapURIToAddonID", e);
+    DevToolsUtils.reportException("mapURIToAddonID", e);
     return false;
   }
 }
 
 /**
  * BreakpointStore objects keep track of all breakpoints that get set so that we
  * can reset them when the same script is introduced to the thread again (such
  * as after a refresh).
@@ -308,16 +320,18 @@ BreakpointStore.prototype = {
     } else {
       for (let column in this._breakpoints[aUrl][aLine]) {
         yield column;
       }
     }
   },
 };
 
+exports.BreakpointStore = BreakpointStore;
+
 /**
  * Manages pushing event loops and automatically pops and exits them in the
  * correct order as they are resolved.
  *
  * @param nsIJSInspector inspector
  *        The underlying JS inspector we use to enter and exit nested event
  *        loops.
  * @param ThreadActor thread
@@ -2393,16 +2407,17 @@ ThreadActor.prototype.requestTypes = {
   "eventListeners": ThreadActor.prototype.onEventListeners,
   "releaseMany": ThreadActor.prototype.onReleaseMany,
   "setBreakpoint": ThreadActor.prototype.onSetBreakpoint,
   "sources": ThreadActor.prototype.onSources,
   "threadGrips": ThreadActor.prototype.onThreadGrips,
   "prototypesAndProperties": ThreadActor.prototype.onPrototypesAndProperties
 };
 
+exports.ThreadActor = ThreadActor;
 
 /**
  * Creates a PauseActor.
  *
  * PauseActors exist for the lifetime of a given debuggee pause.  Used to
  * scope pause-lifetime grips.
  *
  * @param ActorPool aPool
@@ -3456,16 +3471,17 @@ ObjectActor.prototype.requestTypes = {
   "property": ObjectActor.prototype.onProperty,
   "displayString": ObjectActor.prototype.onDisplayString,
   "ownPropertyNames": ObjectActor.prototype.onOwnPropertyNames,
   "decompile": ObjectActor.prototype.onDecompile,
   "release": ObjectActor.prototype.onRelease,
   "scope": ObjectActor.prototype.onScope,
 };
 
+exports.ObjectActor = ObjectActor;
 
 /**
  * Functions for adding information to ObjectActor grips for the purpose of
  * having customized output. This object holds arrays mapped by
  * Debugger.Object.prototype.class.
  *
  * In each array you can add functions that take two
  * arguments:
@@ -4231,16 +4247,17 @@ LongStringActor.prototype = {
   },
 };
 
 LongStringActor.prototype.requestTypes = {
   "substring": LongStringActor.prototype.onSubstring,
   "release": LongStringActor.prototype.onRelease
 };
 
+exports.LongStringActor = LongStringActor;
 
 /**
  * Creates an actor for the specified stack frame.
  *
  * @param aFrame Debugger.Frame
  *        The debuggee frame.
  * @param aThreadActor ThreadActor
  *        The parent thread actor for this frame.
@@ -4642,16 +4659,18 @@ EnvironmentActor.prototype = {
   }
 };
 
 EnvironmentActor.prototype.requestTypes = {
   "assign": EnvironmentActor.prototype.onAssign,
   "bindings": EnvironmentActor.prototype.onBindings
 };
 
+exports.EnvironmentActor = EnvironmentActor;
+
 /**
  * Override the toString method in order to get more meaningful script output
  * for debugging the debugger.
  */
 Debugger.Script.prototype.toString = function() {
   let output = "";
   if (this.url) {
     output += this.url;
@@ -4743,16 +4762,18 @@ update(ChromeDebuggerActor.prototype, {
         type: "newGlobal",
         // TODO: after bug 801084 lands see if we need to JSONify this.
         hostAnnotations: aGlobal.hostAnnotations
       });
     }
   }
 });
 
+exports.ChromeDebuggerActor = ChromeDebuggerActor;
+
 /**
  * Creates an actor for handling add-on debugging. AddonThreadActor is
  * a thin wrapper over ThreadActor.
  *
  * @param aConnection object
  *        The DebuggerServerConnection with which this AddonThreadActor
  *        is associated. (Currently unused, but required to make this
  *        constructor usable with addGlobalActor.)
@@ -4918,16 +4939,18 @@ update(AddonThreadActor.prototype, {
   }
 });
 
 AddonThreadActor.prototype.requestTypes = Object.create(ThreadActor.prototype.requestTypes);
 update(AddonThreadActor.prototype.requestTypes, {
   "attach": AddonThreadActor.prototype.onAttach
 });
 
+exports.AddonThreadActor = AddonThreadActor;
+
 /**
  * Manages the sources for a thread. Handles source maps, locations in the
  * sources, etc for ThreadActors.
  */
 function ThreadSources(aThreadActor, aUseSourceMaps, aAllowPredicate,
                        aOnNewSource) {
   this._thread = aThreadActor;
   this._useSourceMaps = aUseSourceMaps;
@@ -5280,16 +5303,18 @@ ThreadSources.prototype = {
 
   iter: function* () {
     for (let url in this._sourceActors) {
       yield this._sourceActors[url];
     }
   }
 };
 
+exports.ThreadSources = ThreadSources;
+
 // Utility functions.
 
 // TODO bug 863089: use Debugger.Script.prototype.getOffsetColumn when it is
 // implemented.
 function getOffsetColumn(aOffset, aScript) {
   let bestOffsetMapping = null;
   for (let offsetMapping of aScript.getAllColumnOffsets()) {
     if (!bestOffsetMapping ||
@@ -5388,17 +5413,17 @@ function fetch(aURL, aOptions={ loadFrom
   }
 
   switch (scheme) {
     case "file":
     case "chrome":
     case "resource":
       try {
         NetUtil.asyncFetch(url, function onFetch(aStream, aStatus, aRequest) {
-          if (!Components.isSuccessCode(aStatus)) {
+          if (!components.isSuccessCode(aStatus)) {
             deferred.reject(new Error("Request failed with status code = "
                                       + aStatus
                                       + " after NetUtil.asyncFetch for url = "
                                       + url));
             return;
           }
 
           let source = NetUtil.readInputStreamToString(aStream, aStream.available());
@@ -5419,28 +5444,28 @@ function fetch(aURL, aOptions={ loadFrom
         // On Windows xpcshell tests, c:/foo/bar can pass as a valid URL, but
         // newChannel won't be able to handle it.
         url = "file:///" + url;
         channel = Services.io.newChannel(url, null, null);
       }
       let chunks = [];
       let streamListener = {
         onStartRequest: function(aRequest, aContext, aStatusCode) {
-          if (!Components.isSuccessCode(aStatusCode)) {
+          if (!components.isSuccessCode(aStatusCode)) {
             deferred.reject(new Error("Request failed with status code = "
                                       + aStatusCode
                                       + " in onStartRequest handler for url = "
                                       + url));
           }
         },
         onDataAvailable: function(aRequest, aContext, aStream, aOffset, aCount) {
           chunks.push(NetUtil.readInputStreamToString(aStream, aCount));
         },
         onStopRequest: function(aRequest, aContext, aStatusCode) {
-          if (!Components.isSuccessCode(aStatusCode)) {
+          if (!components.isSuccessCode(aStatusCode)) {
             deferred.reject(new Error("Request failed with status code = "
                                       + aStatusCode
                                       + " in onStopRequest handler for url = "
                                       + url));
             return;
           }
 
           charset = channel.contentCharset;
@@ -5595,8 +5620,20 @@ function makeDebuggeeValueIfNeeded(obj, 
   }
   return value;
 }
 
 function getInnerId(window) {
   return window.QueryInterface(Ci.nsIInterfaceRequestor).
                 getInterface(Ci.nsIDOMWindowUtils).currentInnerWindowID;
 };
+
+exports.register = function(handle) {
+  ThreadActor.breakpointStore = new BreakpointStore();
+  ThreadSources._blackBoxedSources = new Set(["self-hosted"]);
+  ThreadSources._prettyPrintedSources = new Map();
+};
+
+exports.unregister = function(handle) {
+  ThreadActor.breakpointStore = null;
+  ThreadSources._blackBoxedSources.clear();
+  ThreadSources._prettyPrintedSources.clear();
+};
--- a/toolkit/devtools/server/actors/webbrowser.js
+++ b/toolkit/devtools/server/actors/webbrowser.js
@@ -1,22 +1,23 @@
 /* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ft=javascript ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
-let {Ci,Cu} = require("chrome");
-let {createExtraActors, appendExtraActors} = require("devtools/server/actors/common");
+let { Ci, Cu } = require("chrome");
+let Services = require("Services");
+let { createExtraActors, appendExtraActors } = require("devtools/server/actors/common");
+let { AddonThreadActor, ThreadActor } = require("devtools/server/actors/script");
 let DevToolsUtils = require("devtools/toolkit/DevToolsUtils");
 
 let {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
-Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "AddonManager", "resource://gre/modules/AddonManager.jsm");
 
 // Assumptions on events module:
 // events needs to be dispatched synchronously,
 // by calling the listeners in the order or registration.
 XPCOMUtils.defineLazyGetter(this, "events", () => {
--- a/toolkit/devtools/server/actors/webconsole.js
+++ b/toolkit/devtools/server/actors/webconsole.js
@@ -1,27 +1,23 @@
 /* -*- js2-basic-offset: 2; indent-tabs-mode: nil; -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
-let {Cc, Ci, Cu} = require("chrome");
+const { Cc, Ci, Cu } = require("chrome");
+const Debugger = require("Debugger");
+const { DebuggerServer, ActorPool } = require("devtools/server/main");
+const { EnvironmentActor, LongStringActor, ObjectActor, ThreadActor } = require("devtools/server/actors/script");
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
-let { DebuggerServer, ActorPool } = require("devtools/server/main");
-// Symbols from script.js
-let { ThreadActor, EnvironmentActor, ObjectActor, LongStringActor } = DebuggerServer;
-
-Cu.import("resource://gre/modules/jsdebugger.jsm");
-addDebuggerToGlobal(this);
-
 XPCOMUtils.defineLazyModuleGetter(this, "Services",
                                   "resource://gre/modules/Services.jsm");
 XPCOMUtils.defineLazyGetter(this, "NetworkMonitor", () => {
   return require("devtools/toolkit/webconsole/network-monitor")
          .NetworkMonitor;
 });
 XPCOMUtils.defineLazyGetter(this, "NetworkMonitorChild", () => {
   return require("devtools/toolkit/webconsole/network-monitor")
--- a/toolkit/devtools/server/main.js
+++ b/toolkit/devtools/server/main.js
@@ -341,17 +341,18 @@ var DebuggerServer = {
    * root actor.
    */
   addBrowserActors: function(aWindowType = "navigator:browser", restrictPrivileges = false) {
     this.chromeWindowType = aWindowType;
     this.addActors("resource://gre/modules/devtools/server/actors/webbrowser.js");
 
     if (!restrictPrivileges) {
       this.addTabActors();
-      this.addGlobalActor(this.ChromeDebuggerActor, "chromeDebugger");
+      let { ChromeDebuggerActor } = require("devtools/server/actors/script");
+      this.addGlobalActor(ChromeDebuggerActor, "chromeDebugger");
       this.registerModule("devtools/server/actors/preference");
     }
 
     this.addActors("resource://gre/modules/devtools/server/actors/webapps.js");
     this.registerModule("devtools/server/actors/device");
   },
 
   /**
@@ -372,17 +373,17 @@ var DebuggerServer = {
       this.addActors("resource://gre/modules/devtools/server/actors/childtab.js");
     }
   },
 
   /**
    * Install tab actors.
    */
   addTabActors: function() {
-    this.addActors("resource://gre/modules/devtools/server/actors/script.js");
+    this.registerModule("devtools/server/actors/script");
     this.registerModule("devtools/server/actors/webconsole");
     this.registerModule("devtools/server/actors/inspector");
     this.registerModule("devtools/server/actors/call-watcher");
     this.registerModule("devtools/server/actors/canvas");
     this.registerModule("devtools/server/actors/webgl");
     this.registerModule("devtools/server/actors/webaudio");
     this.registerModule("devtools/server/actors/stylesheets");
     this.registerModule("devtools/server/actors/styleeditor");
--- a/toolkit/devtools/server/tests/unit/head_dbg.js
+++ b/toolkit/devtools/server/tests/unit/head_dbg.js
@@ -3,20 +3,20 @@
 
 "use strict";
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 const Cr = Components.results;
 
 const { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
+const {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
+
 const Services = devtools.require("Services");
-const { ActorPool, createExtraActors, appendExtraActors } = devtools.require("devtools/server/actors/common");
 const DevToolsUtils = devtools.require("devtools/toolkit/DevToolsUtils.js");
-const {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
 
 // Always log packets when running tests. runxpcshelltests.py will throw
 // the output away anyway, unless you give it the --verbose flag.
 Services.prefs.setBoolPref("devtools.debugger.log", true);
 // Enable remote debugging for the relevant tests.
 Services.prefs.setBoolPref("devtools.debugger.remote-enabled", true);
 
 function tryImport(url) {
@@ -29,16 +29,18 @@ function tryImport(url) {
   }
 }
 
 tryImport("resource://gre/modules/devtools/dbg-server.jsm");
 tryImport("resource://gre/modules/devtools/dbg-client.jsm");
 tryImport("resource://gre/modules/devtools/Loader.jsm");
 tryImport("resource://gre/modules/devtools/Console.jsm");
 
+let { BreakpointStore, LongStringActor, ThreadActor } = devtools.require("devtools/server/actors/script");
+
 function testExceptionHook(ex) {
   try {
     do_report_unexpected_exception(ex);
   } catch(ex) {
     return {throw: ex}
   }
   return undefined;
 }
@@ -177,26 +179,26 @@ function attachTestTabAndResume(aClient,
 }
 
 /**
  * Initialize the testing debugger server.
  */
 function initTestDebuggerServer()
 {
   DebuggerServer.addActors("resource://gre/modules/devtools/server/actors/root.js");
-  DebuggerServer.addActors("resource://gre/modules/devtools/server/actors/script.js");
+  DebuggerServer.registerModule("devtools/server/actors/script");
   DebuggerServer.addActors("resource://test/testactors.js");
   // Allow incoming connections.
   DebuggerServer.init(function () { return true; });
 }
 
 function initTestTracerServer()
 {
   DebuggerServer.addActors("resource://gre/modules/devtools/server/actors/root.js");
-  DebuggerServer.addActors("resource://gre/modules/devtools/server/actors/script.js");
+  DebuggerServer.registerModule("devtools/server/actors/script");
   DebuggerServer.addActors("resource://test/testactors.js");
   DebuggerServer.registerModule("devtools/server/actors/tracer");
   // Allow incoming connections.
   DebuggerServer.init(function () { return true; });
 }
 
 function finishClient(aClient)
 {
--- a/toolkit/devtools/server/tests/unit/test_breakpointstore.js
+++ b/toolkit/devtools/server/tests/unit/test_breakpointstore.js
@@ -3,19 +3,16 @@
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Test the functionality of the BreakpointStore object.
 
 function run_test()
 {
   Cu.import("resource://gre/modules/jsdebugger.jsm");
   addDebuggerToGlobal(this);
-  let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
-    .getService(Components.interfaces.mozIJSSubScriptLoader);
-  loader.loadSubScript("resource://gre/modules/devtools/server/actors/script.js");
 
   test_has_breakpoint();
   test_bug_754251();
   test_add_breakpoint();
   test_remove_breakpoint();
   test_find_breakpoints();
 }
 
--- a/toolkit/devtools/server/tests/unit/test_longstringactor.js
+++ b/toolkit/devtools/server/tests/unit/test_longstringactor.js
@@ -1,19 +1,16 @@
 /* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; js-indent-level: 2; -*- */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 function run_test()
 {
   Cu.import("resource://gre/modules/jsdebugger.jsm");
   addDebuggerToGlobal(this);
-  let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
-    .getService(Components.interfaces.mozIJSSubScriptLoader);
-  loader.loadSubScript("resource://gre/modules/devtools/server/actors/script.js");
 
   test_LSA_disconnect();
   test_LSA_grip();
   test_LSA_onSubstring();
 }
 
 const TEST_STRING = "This is a very long string!";
 
--- a/toolkit/devtools/server/tests/unit/testactors.js
+++ b/toolkit/devtools/server/tests/unit/testactors.js
@@ -1,11 +1,15 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
+const Cu = Components.utils;
+const devtools = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools;
+const { ThreadActor } = devtools.require("devtools/server/actors/script");
+
 var gTestGlobals = [];
 DebuggerServer.addTestGlobal = function(aGlobal) {
   gTestGlobals.push(aGlobal);
 };
 
 // A mock tab list, for use by tests. This simply presents each global in
 // gTestGlobals as a tab, and the list is fixed: it never calls its
 // onListChanged handler.