Bug 1230990 - Wait for the source text to finish loading before signaling that source has been shown in the debugger. r?ochameau draft
authorSami Jaktholm <sjakthol@outlook.com>
Sat, 21 May 2016 10:50:51 +0300
changeset 372924 d1036008e3961097e6b96eb1ded99bfe4b015f86
parent 372916 4dbe106594fa8197404081eb801cbd4b2a42d06b
child 522284 6793347600cc40ce0fd5a73538f32cdac790a0e2
push id19635
push usersjakthol@outlook.com
push dateMon, 30 May 2016 16:15:44 +0000
reviewersochameau
bugs1230990
milestone49.0a1
Bug 1230990 - Wait for the source text to finish loading before signaling that source has been shown in the debugger. r?ochameau Currently viewSourceInDebugger() only waits for a source to be shown if it is not the selected one. If the requested source is selected by default, it might already be selected when the isLoading check is made. However, the actual source text might still be loading since it is loaded asynchronously. In this case the method does not wait for the source to be shown meaning the method resolves before the source is ready in the debugger. This causes browser_toolbox_view_source_01.js to fail intermittently with wrong line number since it looks at the focused line BEFORE the source text has loaded and the correct line is selected. This changeset modifies the behavior of viewSourceInDebugger() to also wait for source shown event if the source is already selected but still loading. MozReview-Commit-ID: JvxjJ5Yt19a
devtools/client/shared/view-source.js
--- a/devtools/client/shared/view-source.js
+++ b/devtools/client/shared/view-source.js
@@ -3,16 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 var { Task } = require("devtools/shared/task");
 
 var Services = require("Services");
 var {gDevTools} = require("devtools/client/framework/devtools");
+var { getSourceText } = require("devtools/client/debugger/content/queries");
 
 /**
  * Tries to open a Stylesheet file in the Style Editor. If the file is not
  * found, it is opened in source view instead.
  * Returns a promise resolving to a boolean indicating whether or not
  * the source was able to be displayed in the StyleEditor, as the built-in
  * Firefox View Source is the fallback.
  *
@@ -62,22 +63,45 @@ exports.viewSourceInDebugger = Task.asyn
   }
 
   let { DebuggerView } = dbg;
   let { Sources } = DebuggerView;
 
   let item = Sources.getItemForAttachment(a => a.source.url === sourceURL);
   if (item) {
     yield toolbox.selectTool("jsdebugger");
-    const isLoading = dbg.DebuggerController.getState().sources.selectedSource
-                      !== item.attachment.source.actor;
-    DebuggerView.setEditorLocation(item.attachment.source.actor, sourceLine, {
-      noDebug: true
-    });
-    if (isLoading) {
+
+    // Determine if the source has already finished loading. There's two cases
+    // in which we need to wait for the source to be shown:
+    // 1) The requested source is not yet selected and will be shown once it is
+    //    selected and loaded
+    // 2) The requested source is selected BUT the source text is still loading.
+    const { actor } = item.attachment.source;
+    const state = dbg.DebuggerController.getState();
+
+    // (1) Is the source selected?
+    const selected = state.sources.selectedSource;
+    const isSelected = selected === actor;
+
+    // (2) Has the source text finished loading?
+    let isLoading = false;
+
+    // Only check if the source is loading when the source is already selected.
+    // If the source is not selected, we will select it below and the already
+    // pending load will be cancelled and this check is useless.
+    if (isSelected) {
+      const sourceTextInfo = getSourceText(state, selected);
+      isLoading = sourceTextInfo && sourceTextInfo.loading;
+    }
+
+    // Select the requested source
+    DebuggerView.setEditorLocation(actor, sourceLine, { noDebug: true });
+
+    // Wait for it to load
+    if (!isSelected || isLoading) {
       yield dbg.DebuggerController.waitForSourceShown(sourceURL);
     }
     return true;
   }
 
   // If not found, still attempt to open in View Source
   exports.viewSource(toolbox, sourceURL, sourceLine);
   return false;