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
--- 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;