bug 755661 part 4 - debugger frontend use the sources over protocol; r=past
authorNick Fitzgerald <fitzgen@gmail.com>
Thu, 27 Sep 2012 11:31:00 +0300
changeset 109262 5fa320921d85b75c5493134490473bd1bf289c54
parent 109261 055b04db33a19e50c672a5c56f503dbdb3055d8d
child 109263 ac84886e4d05a6effd913d3f778d2ba981c6c3ae
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
reviewerspast
bugs755661
milestone18.0a1
bug 755661 part 4 - debugger frontend use the sources over protocol; r=past
browser/devtools/debugger/debugger-controller.js
browser/devtools/debugger/debugger-view.js
--- a/browser/devtools/debugger/debugger-controller.js
+++ b/browser/devtools/debugger/debugger-controller.js
@@ -924,17 +924,21 @@ SourceScripts.prototype = {
    * Handler for the debugger client's unsolicited newScript notification.
    */
   _onNewScript: function SS__onNewScript(aNotification, aPacket) {
     // Ignore scripts generated from 'clientEvaluate' packets.
     if (aPacket.url == "debugger eval code") {
       return;
     }
 
-    this._addScript({ url: aPacket.url, startLine: aPacket.startLine }, true);
+    this._addScript({
+      url: aPacket.url,
+      startLine: aPacket.startLine,
+      source: aPacket.source
+    }, true);
 
     let preferredScriptUrl = DebuggerView.Scripts.preferredScriptUrl;
 
     // Select this script if it's the preferred one.
     if (aPacket.url === DebuggerView.Scripts.preferredScriptUrl) {
       DebuggerView.Scripts.selectScript(aPacket.url);
     }
     // ..or the first entry if there's not one selected yet.
@@ -1212,17 +1216,17 @@ SourceScripts.prototype = {
 
     let editor = DebuggerView.editor;
     editor.setMode(SourceEditor.MODES.TEXT);
     editor.setText(L10N.getStr("loadingText"));
     editor.resetUndo();
 
     // Notify that we need to load a script file.
     DebuggerController.dispatchEvent("Debugger:LoadSource", {
-      url: aScript.url,
+      script: aScript,
       options: aOptions
     });
   },
 
   /**
    * Display the script source once it loads.
    *
    * @private
@@ -1251,128 +1255,82 @@ SourceScripts.prototype = {
 
     // Notify that we shown script file.
     DebuggerController.dispatchEvent("Debugger:ScriptShown", {
       url: aScript.url
     });
   },
 
   /**
-   * Handles notifications to load a source script from the cache or from a
-   * local file.
-   *
-   * XXX: It may be better to use nsITraceableChannel to get to the sources
-   * without relying on caching when we can (not for eval, etc.):
-   * http://www.softwareishard.com/blog/firebug/nsitraceablechannel-intercept-http-traffic/
+   * Handles notifications to load a source script.
    */
   _onLoadSource: function SS__onLoadSource(aEvent) {
-    let url = aEvent.detail.url;
+    let script = aEvent.detail.script;
     let options = aEvent.detail.options;
-    let self = this;
 
-    switch (Services.io.extractScheme(url)) {
-      case "file":
-      case "chrome":
-      case "resource":
-        try {
-          NetUtil.asyncFetch(url, function onFetch(aStream, aStatus) {
-            if (!Components.isSuccessCode(aStatus)) {
-              return self._logError(url, aStatus);
-            }
-            let source = NetUtil.readInputStreamToString(aStream, aStream.available());
-            source = self._convertToUnicode(source);
-            self._onLoadSourceFinished(url, source, null, options);
-            aStream.close();
-          });
-        } catch (ex) {
-          return self._logError(url, ex.name);
-        }
-        break;
+    let sourceClient = this.activeThread.source(script.source);
+    sourceClient.source(function (aResponse) {
+      if (aResponse.error) {
+        return this._logError(script.url, -1);
+      }
 
-      default:
-        let channel = Services.io.newChannel(url, null, null);
-        let chunks = [];
-        let streamListener = {
-          onStartRequest: function(aRequest, aContext, aStatusCode) {
-            if (!Components.isSuccessCode(aStatusCode)) {
-              return self._logError(url, aStatusCode);
-            }
-          },
-          onDataAvailable: function(aRequest, aContext, aStream, aOffset, aCount) {
-            chunks.push(NetUtil.readInputStreamToString(aStream, aCount));
-          },
-          onStopRequest: function(aRequest, aContext, aStatusCode) {
-            if (!Components.isSuccessCode(aStatusCode)) {
-              return self._logError(url, aStatusCode);
-            }
-            let source = self._convertToUnicode(chunks.join(""), channel.contentCharset);
-            self._onLoadSourceFinished(url, source, channel.contentType, options);
-          }
-        };
+      if (typeof aResponse.source === "string") {
+        // We did not receive a long string, instead we got the source directly.
+        this._onLoadSourceFinished(script.url,
+                                   aResponse.source,
+                                   options);
+        return;
+      }
+
+      if (aResponse.source.type !== "longString") {
+        return this._logError(script.url, -1);
+      }
 
-        channel.loadFlags = channel.LOAD_FROM_CACHE;
-        channel.asyncOpen(streamListener, null);
-        break;
-    }
-  },
-
-  /**
-   * Convert a given string, encoded in a given character set, to unicode.
-   * @param string aString
-   *        A string.
-   * @param string aCharset
-   *        A character set.
-   * @return string
-   *         A unicode string.
-   */
-  _convertToUnicode: function SS__convertToUnicode(aString, aCharset) {
-    // Decoding primitives.
-    let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
-        .createInstance(Ci.nsIScriptableUnicodeConverter);
-
-    try {
-      converter.charset = aCharset || "UTF-8";
-      return converter.ConvertToUnicode(aString);
-    } catch(e) {
-      return aString;
-    }
+      let sourceTextClient = this.activeThread.threadLongString(aResponse.source);
+      let length = sourceTextClient.length;
+      sourceTextClient.substring(0, length, function (aResponse) {
+        if (aResponse.error) {
+          return this._logError(script.url, -1);
+        }
+        this._onLoadSourceFinished(script.url,
+                                   aResponse.substring,
+                                   options);
+      }.bind(this));
+    }.bind(this));
   },
 
   /**
    * Called when a script's source has been loaded.
    *
    * @private
    * @param string aScriptUrl
    *        The URL of the source script.
    * @param string aSourceText
    *        The text of the source script.
-   * @param string aContentType
-   *        The content type of the source script.
    * @param object aOptions [optional]
    *        Additional options for showing the script. Supported options:
    *        - targetLine: place the editor at the given line number.
    */
   _onLoadSourceFinished:
-  function SS__onLoadSourceFinished(aScriptUrl, aSourceText, aContentType, aOptions) {
+  function SS__onLoadSourceFinished(aScriptUrl, aSourceText, aOptions) {
     let element = DebuggerView.Scripts.getScriptByLocation(aScriptUrl);
 
     // Tab navigated before we got a chance to finish loading and displaying
     // the source. The outcome is that the expected url is not present anymore
     // in the scripts container, hence the original script object coming from
     // the active thread no longer exists. There's really nothing that needs
     // to be done in this case, nor something that can be currently avoided.
     if (!element) {
       return;
     }
 
     let script = element.getUserData("sourceScript");
 
     script.loaded = true;
     script.text = aSourceText;
-    script.contentType = aContentType;
     element.setUserData("sourceScript", script, null);
 
     if (aOptions.silent) {
       aOptions.callback && aOptions.callback(aScriptUrl, aSourceText);
       return;
     }
 
     this.showScript(script, aOptions);
--- a/browser/devtools/debugger/debugger-view.js
+++ b/browser/devtools/debugger/debugger-view.js
@@ -463,17 +463,17 @@ GlobalSearchView.prototype = {
     }
 
     // Fetch each new script's source.
     for (let url of aUrls) {
       if (this._scriptSources.has(url)) {
         continue;
       }
       DebuggerController.dispatchEvent("Debugger:LoadSource", {
-        url: url,
+        script: DebuggerView.Scripts.getScriptByLocation(url).getUserData("sourceScript"),
         options: {
           silent: true,
           callback: aFetchCallback
         }
       });
     }
   },