Bug 919819 - Detect JS files from fetched content type. r=fitzgen

--HG--
rename : browser/devtools/debugger/test/browser_dbg_pretty-print-01.js => browser/devtools/debugger/test/browser_dbg_pretty-print-13.js
rename : browser/devtools/debugger/test/code_ugly.js => browser/devtools/debugger/test/code_ugly-8
rename : browser/devtools/debugger/test/doc_pretty-print.html => browser/devtools/debugger/test/doc_pretty-print-3.html
This commit is contained in:
J. Ryan Stinnett 2014-02-11 15:35:11 -06:00
parent 10ea4070d4
commit 71772e679e
9 changed files with 136 additions and 11 deletions

View File

@ -29,6 +29,9 @@ const EVENTS = {
SOURCE_SHOWN: "Debugger:EditorSourceShown",
SOURCE_ERROR_SHOWN: "Debugger:EditorSourceErrorShown",
// When the editor has shown a source and set the line / column position
EDITOR_LOCATION_SET: "Debugger:EditorLocationSet",
// When scopes, variables, properties and watch expressions are fetched and
// displayed in the variables view.
FETCHED_SCOPES: "Debugger:FetchedScopes",
@ -1300,7 +1303,7 @@ SourceScripts.prototype = {
deferred.promise.pretty = wantPretty;
this._cache.set(aSource.url, deferred.promise);
const afterToggle = ({ error, message, source: text }) => {
const afterToggle = ({ error, message, source: text, contentType }) => {
if (error) {
// Revert the rejected promise from the cache, so that the original
// source's text may be shown when the source is selected.
@ -1308,7 +1311,7 @@ SourceScripts.prototype = {
deferred.reject([aSource, message || error]);
return;
}
deferred.resolve([aSource, text]);
deferred.resolve([aSource, text, contentType]);
};
if (wantPretty) {
@ -1360,14 +1363,15 @@ SourceScripts.prototype = {
}
// Get the source text from the active thread.
this.activeThread.source(aSource).source(({ error, message, source: text }) => {
this.activeThread.source(aSource)
.source(({ error, message, source: text, contentType }) => {
if (aOnTimeout) {
window.clearTimeout(fetchTimeout);
}
if (error) {
deferred.reject([aSource, message || error]);
} else {
deferred.resolve([aSource, text]);
deferred.resolve([aSource, text, contentType]);
}
});
@ -1406,13 +1410,13 @@ SourceScripts.prototype = {
}
/* Called if fetching a source finishes successfully. */
function onFetch([aSource, aText]) {
function onFetch([aSource, aText, aContentType]) {
// If fetching the source has previously timed out, discard it this time.
if (!pending.has(aSource.url)) {
return;
}
pending.delete(aSource.url);
fetched.push([aSource.url, aText]);
fetched.push([aSource.url, aText, aContentType]);
maybeFinish();
}

View File

@ -388,7 +388,8 @@ let DebuggerView = {
this._setEditorText(L10N.getStr("loadingText"));
this._editorSource = { url: aSource.url, promise: deferred.promise };
DebuggerController.SourceScripts.getText(aSource).then(([, aText]) => {
DebuggerController.SourceScripts.getText(aSource)
.then(([, aText, aContentType]) => {
// Avoid setting an unexpected source. This may happen when switching
// very fast between sources that haven't been fetched yet.
if (this._editorSource.url != aSource.url) {
@ -396,7 +397,7 @@ let DebuggerView = {
}
this._setEditorText(aText);
this._setEditorMode(aSource.url, aSource.contentType, aText);
this._setEditorMode(aSource.url, aContentType, aText);
// Synchronize any other components with the currently displayed source.
DebuggerView.Sources.selectedValue = aSource.url;
@ -406,7 +407,7 @@ let DebuggerView = {
// Resolve and notify that a source file was shown.
window.emit(EVENTS.SOURCE_SHOWN, aSource);
deferred.resolve([aSource, aText]);
deferred.resolve([aSource, aText, aContentType]);
},
([, aError]) => {
let msg = L10N.getStr("errorLoadingText") + DevToolsUtils.safeErrorString(aError);
@ -466,10 +467,14 @@ let DebuggerView = {
// Make sure the requested source client is shown in the editor, then
// update the source editor's caret position and debug location.
return this._setEditorSource(sourceForm, aFlags).then(() => {
return this._setEditorSource(sourceForm, aFlags)
.then(([,, aContentType]) => {
// Record the contentType learned from fetching
sourceForm.contentType = aContentType;
// Line numbers in the source editor should start from 1. If invalid
// or not specified, then don't do anything.
if (aLine < 1) {
window.emit(EVENTS.EDITOR_LOCATION_SET);
return;
}
if (aFlags.charOffset) {
@ -485,6 +490,7 @@ let DebuggerView = {
if (!aFlags.noDebug) {
this.editor.setDebugLocation(aLine - 1);
}
window.emit(EVENTS.EDITOR_LOCATION_SET);
}).then(null, console.error);
},

View File

@ -28,6 +28,8 @@ support-files =
code_ugly-5.js
code_ugly-6.js
code_ugly-7.js
code_ugly-8
code_ugly-8^headers^
doc_auto-pretty-print-01.html
doc_auto-pretty-print-02.html
doc_binary_search.html
@ -56,6 +58,7 @@ support-files =
doc_pause-exceptions.html
doc_pretty-print.html
doc_pretty-print-2.html
doc_pretty-print-3.html
doc_random-javascript.html
doc_recursion-stack.html
doc_scope-variable.html
@ -161,6 +164,7 @@ support-files =
[browser_dbg_pretty-print-10.js]
[browser_dbg_pretty-print-11.js]
[browser_dbg_pretty-print-12.js]
[browser_dbg_pretty-print-13.js]
[browser_dbg_progress-listener-bug.js]
[browser_dbg_reload-preferred-script-01.js]
[browser_dbg_reload-preferred-script-02.js]

View File

@ -0,0 +1,87 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that clicking the pretty print button prettifies the source, even
* when the source URL does not end in ".js", but the content type is
* JavaScript.
*/
const TAB_URL = EXAMPLE_URL + "doc_pretty-print-3.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gEditor, gSources;
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gSources = gDebugger.DebuggerView.Sources;
promise.all([waitForSourceShown(gPanel, "code_ugly-8"),
waitForEditorLocationSet(gPanel)])
.then(testSourceIsUgly)
.then(() => {
const finished = waitForSourceShown(gPanel, "code_ugly-8");
clickPrettyPrintButton();
testProgressBarShown();
return finished;
})
.then(testSourceIsPretty)
.then(testEditorShown)
.then(testSourceIsStillPretty)
.then(() => closeDebuggerAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(aError));
});
});
}
function testSourceIsUgly() {
ok(!gEditor.getText().contains("\n "),
"The source shouldn't be pretty printed yet.");
}
function clickPrettyPrintButton() {
gDebugger.document.getElementById("pretty-print").click();
}
function testProgressBarShown() {
const deck = gDebugger.document.getElementById("editor-deck");
is(deck.selectedIndex, 2, "The progress bar should be shown");
}
function testSourceIsPretty() {
ok(gEditor.getText().contains("\n "),
"The source should be pretty printed.")
}
function testEditorShown() {
const deck = gDebugger.document.getElementById("editor-deck");
is(deck.selectedIndex, 0, "The editor should be shown");
}
function testSourceIsStillPretty() {
const deferred = promise.defer();
const { source } = gSources.selectedItem.attachment;
gDebugger.DebuggerController.SourceScripts.getText(source).then(([, text]) => {
ok(text.contains("\n "),
"Subsequent calls to getText return the pretty printed source.");
deferred.resolve();
});
return deferred.promise;
}
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gEditor = null;
gSources = null;
});

View File

@ -0,0 +1,3 @@
function foo() { var a=1; var b=2; bar(a, b); }
function bar(c, d) { debugger; }
foo();

View File

@ -0,0 +1 @@
Content-Type: application/javascript

View File

@ -0,0 +1,8 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!DOCTYPE html>
<head>
<meta charset="utf-8"/>
<title>Debugger Pretty Printing Test Page</title>
</head>
<script src="code_ugly-8"></script>

View File

@ -236,6 +236,11 @@ function waitForSourceShown(aPanel, aUrl) {
});
}
function waitForEditorLocationSet(aPanel) {
return waitForDebuggerEvents(aPanel,
aPanel.panelWin.EVENTS.EDITOR_LOCATION_SET);
}
function ensureSourceIs(aPanel, aUrl, aWaitFlag = false) {
if (aPanel.panelWin.DebuggerView.Sources.selectedValue.contains(aUrl)) {
ok(true, "Expected source is shown: " + aUrl);

View File

@ -2460,7 +2460,14 @@ SourceActor.prototype = {
// XXX bug 865252: Don't load from the cache if this is a source mapped
// source because we can't guarantee that the cache has the most up to date
// content for this source like we can if it isn't source mapped.
return fetch(this._url, { loadFromCache: !this._sourceMap });
let sourceFetched = fetch(this._url, { loadFromCache: !this._sourceMap });
// Record the contentType we just learned during fetching
sourceFetched.then(({ contentType }) => {
this._contentType = contentType;
});
return sourceFetched;
},
/**