зеркало из https://github.com/mozilla/gecko-dev.git
Bug 913665 - Detect minified files and pretty print them by default; r=fitzgen
This commit is contained in:
Родитель
f46f9860a6
Коммит
4e53556018
|
@ -1121,6 +1121,7 @@ pref("devtools.debugger.pause-on-exceptions", false);
|
|||
pref("devtools.debugger.ignore-caught-exceptions", true);
|
||||
pref("devtools.debugger.source-maps-enabled", true);
|
||||
pref("devtools.debugger.pretty-print-enabled", true);
|
||||
pref("devtools.debugger.auto-pretty-print", true);
|
||||
pref("devtools.debugger.tracer", false);
|
||||
|
||||
// The default Debugger UI settings
|
||||
|
|
|
@ -2185,6 +2185,7 @@ let Prefs = new ViewHelpers.Prefs("devtools", {
|
|||
ignoreCaughtExceptions: ["Bool", "debugger.ignore-caught-exceptions"],
|
||||
sourceMapsEnabled: ["Bool", "debugger.source-maps-enabled"],
|
||||
prettyPrintEnabled: ["Bool", "debugger.pretty-print-enabled"],
|
||||
autoPrettyPrint: ["Bool", "debugger.auto-pretty-print"],
|
||||
tracerEnabled: ["Bool", "debugger.tracer"],
|
||||
editorTabSize: ["Int", "editor.tabsize"]
|
||||
});
|
||||
|
|
|
@ -3,8 +3,13 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Used to detect minification for automatic pretty printing
|
||||
const SAMPLE_SIZE = 30; // no of lines
|
||||
const INDENT_COUNT_THRESHOLD = 20; // percentage
|
||||
|
||||
/**
|
||||
* Functions handling the sources UI.
|
||||
*/
|
||||
|
@ -769,9 +774,20 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
|||
if (!sourceItem) {
|
||||
return;
|
||||
}
|
||||
const { source } = sourceItem.attachment;
|
||||
const sourceClient = gThreadClient.source(source);
|
||||
|
||||
// The container is not empty and an actual item was selected.
|
||||
DebuggerView.setEditorLocation(sourceItem.value);
|
||||
|
||||
if (Prefs.autoPrettyPrint && !sourceClient.isPrettyPrinted) {
|
||||
DebuggerController.SourceScripts.getText(source).then(([, aText]) => {
|
||||
if (SourceUtils.isMinified(sourceClient, aText)) {
|
||||
this.togglePrettyPrint();
|
||||
}
|
||||
}).then(null, e => DevToolsUtils.reportException("_onSourceSelect", e));
|
||||
}
|
||||
|
||||
// Set window title. No need to split the url by " -> " here, because it was
|
||||
// already sanitized when the source was added.
|
||||
document.title = L10N.getFormatStr("DebuggerWindowScriptTitle", sourceItem.value);
|
||||
|
@ -1432,6 +1448,7 @@ TracerView.prototype = Heritage.extend(WidgetMethods, {
|
|||
let SourceUtils = {
|
||||
_labelsCache: new Map(), // Can't use WeakMaps because keys are strings.
|
||||
_groupsCache: new Map(),
|
||||
_minifiedCache: new WeakMap(),
|
||||
|
||||
/**
|
||||
* Returns true if the specified url and/or content type are specific to
|
||||
|
@ -1446,13 +1463,53 @@ let SourceUtils = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Clears the labels cache, populated by methods like
|
||||
* Determines if the source text is minified by using
|
||||
* the percentage indented of a subset of lines
|
||||
*
|
||||
* @param string aText
|
||||
* The source text.
|
||||
* @return boolean
|
||||
* True if source text is minified.
|
||||
*/
|
||||
isMinified: function(sourceClient, aText){
|
||||
if (this._minifiedCache.has(sourceClient)) {
|
||||
return this._minifiedCache.get(sourceClient);
|
||||
}
|
||||
|
||||
let isMinified;
|
||||
let lineEndIndex = 0;
|
||||
let lineStartIndex = 0;
|
||||
let lines = 0;
|
||||
let indentCount = 0;
|
||||
|
||||
// Strip comments.
|
||||
aText = aText.replace(/\/\*[\S\s]*?\*\/|\/\/(.+|\n)/g, "");
|
||||
|
||||
while (lines++ < SAMPLE_SIZE) {
|
||||
lineEndIndex = aText.indexOf("\n", lineStartIndex);
|
||||
if (lineEndIndex == -1) {
|
||||
break;
|
||||
}
|
||||
if (/^\s+/.test(aText.slice(lineStartIndex, lineEndIndex))) {
|
||||
indentCount++;
|
||||
}
|
||||
lineStartIndex = lineEndIndex + 1;
|
||||
}
|
||||
isMinified = ((indentCount / lines ) * 100) < INDENT_COUNT_THRESHOLD;
|
||||
|
||||
this._minifiedCache.set(sourceClient, isMinified);
|
||||
return isMinified;
|
||||
},
|
||||
|
||||
/**
|
||||
* Clears the labels, groups and minify cache, populated by methods like
|
||||
* SourceUtils.getSourceLabel or Source Utils.getSourceGroup.
|
||||
* This should be done every time the content location changes.
|
||||
*/
|
||||
clearCache: function() {
|
||||
this._labelsCache.clear();
|
||||
this._groupsCache.clear();
|
||||
this._minifiedCache.clear();
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -196,6 +196,7 @@ ToolbarView.prototype = {
|
|||
function OptionsView() {
|
||||
dumpn("OptionsView was instantiated");
|
||||
|
||||
this._toggleAutoPrettyPrint = this._toggleAutoPrettyPrint.bind(this);
|
||||
this._togglePauseOnExceptions = this._togglePauseOnExceptions.bind(this);
|
||||
this._toggleIgnoreCaughtExceptions = this._toggleIgnoreCaughtExceptions.bind(this);
|
||||
this._toggleShowPanesOnStartup = this._toggleShowPanesOnStartup.bind(this);
|
||||
|
@ -212,6 +213,7 @@ OptionsView.prototype = {
|
|||
dumpn("Initializing the OptionsView");
|
||||
|
||||
this._button = document.getElementById("debugger-options");
|
||||
this._autoPrettyPrint = document.getElementById("auto-pretty-print");
|
||||
this._pauseOnExceptionsItem = document.getElementById("pause-on-exceptions");
|
||||
this._ignoreCaughtExceptionsItem = document.getElementById("ignore-caught-exceptions");
|
||||
this._showPanesOnStartupItem = document.getElementById("show-panes-on-startup");
|
||||
|
@ -219,6 +221,7 @@ OptionsView.prototype = {
|
|||
this._showVariablesFilterBoxItem = document.getElementById("show-vars-filter-box");
|
||||
this._showOriginalSourceItem = document.getElementById("show-original-source");
|
||||
|
||||
this._autoPrettyPrint.setAttribute("checked", Prefs.autoPrettyPrint);
|
||||
this._pauseOnExceptionsItem.setAttribute("checked", Prefs.pauseOnExceptions);
|
||||
this._ignoreCaughtExceptionsItem.setAttribute("checked", Prefs.ignoreCaughtExceptions);
|
||||
this._showPanesOnStartupItem.setAttribute("checked", Prefs.panesVisibleOnStartup);
|
||||
|
@ -257,6 +260,14 @@ OptionsView.prototype = {
|
|||
window.emit(EVENTS.OPTIONS_POPUP_HIDDEN);
|
||||
},
|
||||
|
||||
/**
|
||||
* Listener handling the 'auto pretty print' menuitem command.
|
||||
*/
|
||||
_toggleAutoPrettyPrint: function(){
|
||||
Prefs.autoPrettyPrint =
|
||||
this._autoPrettyPrint.getAttribute("checked") == "true";
|
||||
},
|
||||
|
||||
/**
|
||||
* Listener handling the 'pause on exceptions' menuitem command.
|
||||
*/
|
||||
|
|
|
@ -74,6 +74,8 @@
|
|||
oncommand="DebuggerView.WatchExpressions._onCmdAddExpression()"/>
|
||||
<command id="removeAllWatchExpressionsCommand"
|
||||
oncommand="DebuggerView.WatchExpressions._onCmdRemoveAllExpressions()"/>
|
||||
<command id="toggleAutoPrettyPrint"
|
||||
oncommand="DebuggerView.Options._toggleAutoPrettyPrint()"/>
|
||||
<command id="togglePauseOnExceptions"
|
||||
oncommand="DebuggerView.Options._togglePauseOnExceptions()"/>
|
||||
<command id="toggleIgnoreCaughtExceptions"
|
||||
|
@ -172,6 +174,11 @@
|
|||
onpopupshowing="DebuggerView.Options._onPopupShowing()"
|
||||
onpopuphiding="DebuggerView.Options._onPopupHiding()"
|
||||
onpopuphidden="DebuggerView.Options._onPopupHidden()">
|
||||
<menuitem id="auto-pretty-print"
|
||||
type="checkbox"
|
||||
label="&debuggerUI.autoPrettyPrint;"
|
||||
accesskey="&debuggerUI.autoPrettyPrint.key;"
|
||||
command="toggleAutoPrettyPrint"/>
|
||||
<menuitem id="pause-on-exceptions"
|
||||
type="checkbox"
|
||||
label="&debuggerUI.pauseExceptions;"
|
||||
|
|
|
@ -25,6 +25,11 @@ support-files =
|
|||
code_ugly-2.js
|
||||
code_ugly-3.js
|
||||
code_ugly-4.js
|
||||
code_ugly-5.js
|
||||
code_ugly-6.js
|
||||
code_ugly-7.js
|
||||
doc_auto-pretty-print-01.html
|
||||
doc_auto-pretty-print-02.html
|
||||
doc_binary_search.html
|
||||
doc_blackboxing.html
|
||||
doc_closures.html
|
||||
|
@ -65,6 +70,8 @@ support-files =
|
|||
testactors.js
|
||||
|
||||
[browser_dbg_aaa_run_first_leaktest.js]
|
||||
[browser_dbg_auto-pretty-print-01.js]
|
||||
[browser_dbg_auto-pretty-print-02.js]
|
||||
[browser_dbg_bfcache.js]
|
||||
[browser_dbg_blackboxing-01.js]
|
||||
[browser_dbg_blackboxing-02.js]
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test auto pretty printing.
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_auto-pretty-print-01.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gEditor, gSources, gPrefs, gOptions, gView;
|
||||
|
||||
let gFirstSourceLabel = "code_ugly-5.js";
|
||||
let gSecondSourceLabel = "code_ugly-6.js";
|
||||
|
||||
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;
|
||||
gPrefs = gDebugger.Prefs;
|
||||
gOptions = gDebugger.DebuggerView.Options;
|
||||
gView = gDebugger.DebuggerView;
|
||||
|
||||
// Should be on by default.
|
||||
testAutoPrettyPrintOn();
|
||||
|
||||
waitForSourceShown(gPanel, gFirstSourceLabel)
|
||||
.then(testSourceIsUgly)
|
||||
.then(() => waitForSourceShown(gPanel, gFirstSourceLabel))
|
||||
.then(testSourceIsPretty)
|
||||
.then(disableAutoPrettyPrint)
|
||||
.then(testAutoPrettyPrintOff)
|
||||
.then(() => {
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN);
|
||||
gSources.selectedIndex = 1;
|
||||
return finished;
|
||||
})
|
||||
.then(testSecondSourceLabel)
|
||||
.then(testSourceIsUgly)
|
||||
// Re-enable auto pretty printing for browser_dbg_auto-pretty-print-02.js
|
||||
.then(enableAutoPrettyPrint)
|
||||
.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 testSecondSourceLabel(){
|
||||
ok(gSources.containsValue(EXAMPLE_URL + gSecondSourceLabel),
|
||||
"Second source url is correct.");
|
||||
}
|
||||
|
||||
function testProgressBarShown() {
|
||||
const deck = gDebugger.document.getElementById("editor-deck");
|
||||
is(deck.selectedIndex, 2, "The progress bar should be shown");
|
||||
}
|
||||
|
||||
function testAutoPrettyPrintOn(){
|
||||
is(gPrefs.autoPrettyPrint, true,
|
||||
"The auto-pretty-print pref should be on.");
|
||||
is(gOptions._autoPrettyPrint.getAttribute("checked"), "true",
|
||||
"The Auto pretty print menu item should be checked.");
|
||||
}
|
||||
|
||||
function disableAutoPrettyPrint(){
|
||||
gOptions._autoPrettyPrint.setAttribute("checked", "false");
|
||||
gOptions._toggleAutoPrettyPrint();
|
||||
gOptions._onPopupHidden();
|
||||
}
|
||||
|
||||
function enableAutoPrettyPrint(){
|
||||
gOptions._autoPrettyPrint.setAttribute("checked", "true");
|
||||
gOptions._toggleAutoPrettyPrint();
|
||||
gOptions._onPopupHidden();
|
||||
}
|
||||
|
||||
function testAutoPrettyPrintOff(){
|
||||
is(gPrefs.autoPrettyPrint, false,
|
||||
"The auto-pretty-print pref should be off.");
|
||||
isnot(gOptions._autoPrettyPrint.getAttribute("checked"), "true",
|
||||
"The Auto pretty print menu item should not be checked.");
|
||||
}
|
||||
|
||||
function testSourceIsPretty() {
|
||||
ok(gEditor.getText().contains("\n "),
|
||||
"The source should be pretty printed.")
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gEditor = null;
|
||||
gSources = null;
|
||||
gOptions = null;
|
||||
gPrefs = null;
|
||||
gView = null;
|
||||
});
|
|
@ -0,0 +1,110 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that auto pretty printing doesn't accidentally toggle
|
||||
* pretty printing off when we switch to a minified source
|
||||
* that is already pretty printed.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_auto-pretty-print-02.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gEditor, gSources, gPrefs, gOptions, gView;
|
||||
|
||||
let gFirstSourceLabel = "code_ugly-6.js";
|
||||
let gSecondSourceLabel = "code_ugly-7.js";
|
||||
|
||||
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;
|
||||
gPrefs = gDebugger.Prefs;
|
||||
gOptions = gDebugger.DebuggerView.Options;
|
||||
gView = gDebugger.DebuggerView;
|
||||
|
||||
// Should be on by default.
|
||||
testAutoPrettyPrintOn();
|
||||
|
||||
waitForSourceShown(gPanel, gFirstSourceLabel)
|
||||
.then(testSourceIsUgly)
|
||||
.then(() => waitForSourceShown(gPanel, gFirstSourceLabel))
|
||||
.then(testSourceIsPretty)
|
||||
.then(testPrettyPrintButtonOn)
|
||||
.then(() => {
|
||||
// Switch to the second source.
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN);
|
||||
gSources.selectedIndex = 1;
|
||||
return finished;
|
||||
})
|
||||
.then(testSecondSourceLabel)
|
||||
.then(() => {
|
||||
// Switch back to first source.
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN);
|
||||
gSources.selectedIndex = 0;
|
||||
return finished;
|
||||
})
|
||||
.then(testFirstSourceLabel)
|
||||
.then(testPrettyPrintButtonOn)
|
||||
// Disable auto pretty printing so it does not affect the following tests.
|
||||
.then(disableAutoPrettyPrint)
|
||||
.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 testFirstSourceLabel(){
|
||||
ok(gSources.containsValue(EXAMPLE_URL + gFirstSourceLabel),
|
||||
"First source url is correct.");
|
||||
}
|
||||
|
||||
function testSecondSourceLabel(){
|
||||
ok(gSources.containsValue(EXAMPLE_URL + gSecondSourceLabel),
|
||||
"Second source url is correct.");
|
||||
}
|
||||
|
||||
function testAutoPrettyPrintOn(){
|
||||
is(gPrefs.autoPrettyPrint, true,
|
||||
"The auto-pretty-print pref should be on.");
|
||||
is(gOptions._autoPrettyPrint.getAttribute("checked"), "true",
|
||||
"The Auto pretty print menu item should be checked.");
|
||||
}
|
||||
|
||||
function testPrettyPrintButtonOn(){
|
||||
is(gDebugger.document.getElementById("pretty-print").checked, true,
|
||||
"The button should be checked when the source is selected.");
|
||||
}
|
||||
|
||||
function disableAutoPrettyPrint(){
|
||||
gOptions._autoPrettyPrint.setAttribute("checked", "false");
|
||||
gOptions._toggleAutoPrettyPrint();
|
||||
gOptions._onPopupHidden();
|
||||
}
|
||||
|
||||
function testSourceIsPretty() {
|
||||
ok(gEditor.getText().contains("\n "),
|
||||
"The source should be pretty printed.")
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gEditor = null;
|
||||
gSources = null;
|
||||
gOptions = null;
|
||||
gPrefs = null;
|
||||
gView = null;
|
||||
});
|
|
@ -0,0 +1,14 @@
|
|||
/*1385419625,181944095,JIT Construction: v1021776,en_US*/
|
||||
/**
|
||||
* Copyright Test Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
// Copyright Test Inc.
|
||||
//
|
||||
// etc...
|
||||
// etc...
|
||||
function foo(){var a=1;var b=2;bar(a,b);}
|
||||
function bar(c,d){debugger;}
|
||||
foo();
|
|
@ -0,0 +1,5 @@
|
|||
// Copyright Test Inc.
|
||||
//
|
||||
// etc...
|
||||
// etc...
|
||||
function main(){ return 0; }
|
|
@ -0,0 +1,5 @@
|
|||
// Copyright Test Inc.
|
||||
//
|
||||
// etc...
|
||||
// etc...
|
||||
function foo(){}; foo();
|
|
@ -0,0 +1,14 @@
|
|||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Auto Pretty Printing Test Page</title>
|
||||
</head>
|
||||
<body>
|
||||
<script src="code_ugly-5.js"></script>
|
||||
<script src="code_ugly-6.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,14 @@
|
|||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Auto Pretty Printing Test Page</title>
|
||||
</head>
|
||||
<body>
|
||||
<script src="code_ugly-6.js"></script>
|
||||
<script src="code_ugly-7.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -41,6 +41,11 @@
|
|||
- button that pretty prints the selected source. -->
|
||||
<!ENTITY debuggerUI.sources.prettyPrint "Prettify Source">
|
||||
|
||||
<!-- LOCALIZATION NOTE (debuggerUI.autoPrettyPrint): This is the label for the
|
||||
- checkbox that toggles auto pretty print. -->
|
||||
<!ENTITY debuggerUI.autoPrettyPrint "Auto Prettify Minified Sources">
|
||||
<!ENTITY debuggerUI.autoPrettyPrint.key "P">
|
||||
|
||||
<!-- LOCALIZATION NOTE (debuggerUI.sources.toggleBreakpoints): This is the tooltip for the
|
||||
- button that toggles all breakpoints for all sources. -->
|
||||
<!ENTITY debuggerUI.sources.toggleBreakpoints "Enable/disable all breakpoints">
|
||||
|
@ -66,7 +71,7 @@
|
|||
<!ENTITY debuggerUI.pauseExceptions "Pause on exceptions">
|
||||
<!ENTITY debuggerUI.pauseExceptions.key "E">
|
||||
|
||||
<!-- LOCALIZATION NOTE (debuggerUI.pauseExceptions): This is the label for the
|
||||
<!-- LOCALIZATION NOTE (debuggerUI.ignoreCaughtExceptions): This is the label for the
|
||||
- checkbox that toggles ignoring caught exceptions. -->
|
||||
<!ENTITY debuggerUI.ignoreCaughtExceptions "Ignore caught exceptions">
|
||||
<!ENTITY debuggerUI.ignoreCaughtExceptions.key "C">
|
||||
|
|
Загрузка…
Ссылка в новой задаче