Bug 1416928 - Ensure that cached ContentScript sources are not skipped by the ThreadActor.onNewScript. draft
authorLuca Greco <lgreco@mozilla.com>
Tue, 14 Nov 2017 16:24:12 +0100
changeset 699021 92b0c547ee71bda814307955a6fb49495e0e2e13
parent 697757 b0a6b4678b2f7dfb499328946b95366775f71edd
child 699022 522c0528cf43a8865540eb2216f9a92581281240
child 699107 6f53d53e75b2888834152fc661bd2a0eef8aec38
push id89429
push userluca.greco@alcacoop.it
push dateThu, 16 Nov 2017 10:55:15 +0000
bugs1416928
milestone59.0a1
Bug 1416928 - Ensure that cached ContentScript sources are not skipped by the ThreadActor.onNewScript. MozReview-Commit-ID: JJjcAvsI3Na
devtools/server/actors/script.js
devtools/server/actors/utils/TabSources.js
--- a/devtools/server/actors/script.js
+++ b/devtools/server/actors/script.js
@@ -1944,17 +1944,25 @@ const ThreadActor = ActorClassWithSpec(t
   /**
    * Add the provided source to the server cache.
    *
    * @param aSource Debugger.Source
    *        The source that will be stored.
    * @returns true, if the source was added; false otherwise.
    */
   _addSource: function (source) {
-    if (!this.sources.allowSource(source) || this._debuggerSourcesSeen.has(source)) {
+    if (!this.sources.allowSource(source)) {
+      return false;
+    }
+
+    // Preloaded WebExtension content scripts may be cached internally by
+    // ExtensionContent.jsm and ThreadActor would ignore them on a page reload
+    // because it finds them in the _debuggerSourcesSeen WeakSet,
+    // and so we also need to be sure that there is still a source actor for the source.
+    if (this._debuggerSourcesSeen.has(source) && this.sources.hasSourceActor(source)) {
       return false;
     }
 
     let sourceActor = this.sources.createNonSourceMappedActor(source);
     let bpActors = [...this.breakpointActorMap.findActors()];
 
     if (this._options.useSourceMaps) {
       let promises = [];
--- a/devtools/server/actors/utils/TabSources.js
+++ b/devtools/server/actors/utils/TabSources.js
@@ -209,27 +209,41 @@ TabSources.prototype = {
       this.fetchSourceMap(actor.source).then(map => {
         if (!map) {
           this.emit("newSource", actor);
         }
       });
     }
   },
 
-  getSourceActor: function (source) {
+  _getSourceActor: function (source) {
     if (source.url in this._sourceMappedSourceActors) {
       return this._sourceMappedSourceActors[source.url];
     }
 
     if (this._sourceActors.has(source)) {
       return this._sourceActors.get(source);
     }
 
-    throw new Error("getSource: could not find source actor for " +
-                    (source.url || "source"));
+    return null;
+  },
+
+  hasSourceActor: function (source) {
+    return !!this._getSourceActor(source);
+  },
+
+  getSourceActor: function (source) {
+    const sourceActor = this._getSourceActor(source);
+
+    if (!sourceActor) {
+      throw new Error("getSource: could not find source actor for " +
+                      (source.url || "source"));
+    }
+
+    return sourceActor;
   },
 
   getSourceActorByURL: function (url) {
     if (url) {
       for (let [source, actor] of this._sourceActors) {
         if (source.url === url) {
           return actor;
         }