зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1354672 - update debugger frontend 04/18/17;r=jdescottes
MozReview-Commit-ID: HI2NymoCLYR --HG-- extra : rebase_source : 76cd533614d04771319f484cf8eb642d5f966e75
This commit is contained in:
Родитель
a3cb362804
Коммит
ef9a9e80c9
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -7,6 +7,6 @@ DevToolsModules(
|
|||
'debugger.css',
|
||||
'debugger.js',
|
||||
'panel.js',
|
||||
'parser-worker.js',
|
||||
'pretty-print-worker.js',
|
||||
'source-map-worker.js'
|
||||
)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"use strict";
|
||||
|
||||
const { Task } = require("devtools/shared/task");
|
||||
var {LocalizationHelper} = require("devtools/shared/l10n");
|
||||
var { LocalizationHelper } = require("devtools/shared/l10n");
|
||||
|
||||
const DBG_STRINGS_URI = "devtools/client/locales/debugger.properties";
|
||||
var L10N = new LocalizationHelper(DBG_STRINGS_URI);
|
||||
|
@ -16,38 +16,46 @@ function DebuggerPanel(iframeWindow, toolbox) {
|
|||
}
|
||||
|
||||
DebuggerPanel.prototype = {
|
||||
open: Task.async(function* () {
|
||||
open: async function() {
|
||||
if (!this.toolbox.target.isRemote) {
|
||||
yield this.toolbox.target.makeRemote();
|
||||
await this.toolbox.target.makeRemote();
|
||||
}
|
||||
|
||||
yield this.panelWin.Debugger.bootstrap({
|
||||
const {
|
||||
actions,
|
||||
store,
|
||||
selectors,
|
||||
client
|
||||
} = await this.panelWin.Debugger.bootstrap({
|
||||
threadClient: this.toolbox.threadClient,
|
||||
tabTarget: this.toolbox.target
|
||||
tabTarget: this.toolbox.target,
|
||||
debuggerClient: this.toolbox.target._client,
|
||||
sourceMaps: this.toolbox.sourceMapService
|
||||
});
|
||||
|
||||
this._actions = actions;
|
||||
this._store = store;
|
||||
this._selectors = selectors;
|
||||
this._client = client;
|
||||
this.isReady = true;
|
||||
return this;
|
||||
}),
|
||||
|
||||
_store: function () {
|
||||
return this.panelWin.Debugger.store;
|
||||
},
|
||||
|
||||
_getState: function () {
|
||||
return this._store().getState();
|
||||
getVarsForTests() {
|
||||
return {
|
||||
store: this._store,
|
||||
selectors: this._selectors,
|
||||
actions: this._actions,
|
||||
client: this._client
|
||||
};
|
||||
},
|
||||
|
||||
_actions: function () {
|
||||
return this.panelWin.Debugger.actions;
|
||||
_getState: function() {
|
||||
return this._store.getState();
|
||||
},
|
||||
|
||||
_selectors: function () {
|
||||
return this.panelWin.Debugger.selectors;
|
||||
},
|
||||
|
||||
getFrames: function () {
|
||||
let frames = this._selectors().getFrames(this._getState());
|
||||
getFrames: function() {
|
||||
let frames = this._selectors.getFrames(this._getState());
|
||||
|
||||
// Frames is null when the debugger is not paused.
|
||||
if (!frames) {
|
||||
|
@ -58,7 +66,7 @@ DebuggerPanel.prototype = {
|
|||
}
|
||||
|
||||
frames = frames.toJS();
|
||||
const selectedFrame = this._selectors().getSelectedFrame(this._getState());
|
||||
const selectedFrame = this._selectors.getSelectedFrame(this._getState());
|
||||
const selected = frames.findIndex(frame => frame.id == selectedFrame.id);
|
||||
|
||||
frames.forEach(frame => {
|
||||
|
@ -68,7 +76,15 @@ DebuggerPanel.prototype = {
|
|||
return { frames, selected };
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
selectSource(sourceURL, sourceLine) {
|
||||
this._actions.selectSourceURL(sourceURL, { line: sourceLine });
|
||||
},
|
||||
|
||||
getSource(sourceURL) {
|
||||
return this._selectors.getSourceByURL(this._getState(), sourceURL);
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this.panelWin.Debugger.destroy();
|
||||
this.emit("destroyed");
|
||||
}
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -55,7 +55,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
/***/ 0:
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
module.exports = __webpack_require__(801);
|
||||
module.exports = __webpack_require__(964);
|
||||
|
||||
|
||||
/***/ },
|
||||
|
@ -75,76 +75,6 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
|
||||
/***/ },
|
||||
|
||||
/***/ 801:
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
var prettyFast = __webpack_require__(802);
|
||||
var assert = __webpack_require__(223);
|
||||
|
||||
function prettyPrint(_ref) {
|
||||
var url = _ref.url,
|
||||
indent = _ref.indent,
|
||||
source = _ref.source;
|
||||
|
||||
try {
|
||||
var prettified = prettyFast(source, {
|
||||
url: url,
|
||||
indent: " ".repeat(indent)
|
||||
});
|
||||
|
||||
return {
|
||||
code: prettified.code,
|
||||
mappings: prettified.map._mappings
|
||||
};
|
||||
} catch (e) {
|
||||
throw new Error(`${e.message}\n${e.stack}`);
|
||||
}
|
||||
}
|
||||
|
||||
function invertMappings(mappings) {
|
||||
return mappings._array.map(m => {
|
||||
var mapping = {
|
||||
generated: {
|
||||
line: m.originalLine,
|
||||
column: m.originalColumn
|
||||
}
|
||||
};
|
||||
if (m.source) {
|
||||
mapping.source = m.source;
|
||||
mapping.original = {
|
||||
line: m.generatedLine,
|
||||
column: m.generatedColumn
|
||||
};
|
||||
mapping.name = m.name;
|
||||
}
|
||||
return mapping;
|
||||
});
|
||||
}
|
||||
|
||||
self.onmessage = function (msg) {
|
||||
var _msg$data = msg.data,
|
||||
id = _msg$data.id,
|
||||
args = _msg$data.args;
|
||||
|
||||
assert(msg.data.method === "prettyPrint", "Method must be `prettyPrint`");
|
||||
|
||||
try {
|
||||
var _prettyPrint = prettyPrint(args[0]),
|
||||
code = _prettyPrint.code,
|
||||
mappings = _prettyPrint.mappings;
|
||||
|
||||
self.postMessage({ id, response: {
|
||||
code, mappings: invertMappings(mappings)
|
||||
} });
|
||||
} catch (e) {
|
||||
self.postMessage({ id, error: e });
|
||||
}
|
||||
};
|
||||
|
||||
/***/ },
|
||||
|
||||
/***/ 802:
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
|
@ -5918,6 +5848,80 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
|
||||
|
||||
|
||||
/***/ },
|
||||
|
||||
/***/ 964:
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
var prettyFast = __webpack_require__(802);
|
||||
var assert = __webpack_require__(223);
|
||||
|
||||
function prettyPrint(_ref) {
|
||||
var url = _ref.url,
|
||||
indent = _ref.indent,
|
||||
source = _ref.source;
|
||||
|
||||
try {
|
||||
var prettified = prettyFast(source, {
|
||||
url: url,
|
||||
indent: " ".repeat(indent)
|
||||
});
|
||||
|
||||
return {
|
||||
code: prettified.code,
|
||||
mappings: prettified.map._mappings
|
||||
};
|
||||
} catch (e) {
|
||||
throw new Error(`${e.message}\n${e.stack}`);
|
||||
}
|
||||
}
|
||||
|
||||
function invertMappings(mappings) {
|
||||
return mappings._array.map(m => {
|
||||
var mapping = {
|
||||
generated: {
|
||||
line: m.originalLine,
|
||||
column: m.originalColumn
|
||||
}
|
||||
};
|
||||
if (m.source) {
|
||||
mapping.source = m.source;
|
||||
mapping.original = {
|
||||
line: m.generatedLine,
|
||||
column: m.generatedColumn
|
||||
};
|
||||
mapping.name = m.name;
|
||||
}
|
||||
return mapping;
|
||||
});
|
||||
}
|
||||
|
||||
self.onmessage = function (msg) {
|
||||
var _msg$data = msg.data,
|
||||
id = _msg$data.id,
|
||||
args = _msg$data.args;
|
||||
|
||||
assert(msg.data.method === "prettyPrint", "Method must be `prettyPrint`");
|
||||
|
||||
try {
|
||||
var _prettyPrint = prettyPrint(args[0]),
|
||||
code = _prettyPrint.code,
|
||||
mappings = _prettyPrint.mappings;
|
||||
|
||||
self.postMessage({
|
||||
id,
|
||||
response: {
|
||||
code,
|
||||
mappings: invertMappings(mappings)
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
self.postMessage({ id, error: e });
|
||||
}
|
||||
};
|
||||
|
||||
/***/ }
|
||||
|
||||
/******/ })
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -42,6 +42,7 @@ support-files =
|
|||
[browser_dbg-breakpoints.js]
|
||||
[browser_dbg-breakpoints-cond.js]
|
||||
[browser_dbg-call-stack.js]
|
||||
[browser_dbg-expressions.js]
|
||||
[browser_dbg-scopes.js]
|
||||
[browser_dbg-chrome-create.js]
|
||||
[browser_dbg-chrome-debugging.js]
|
||||
|
|
|
@ -54,6 +54,6 @@ add_task(function* () {
|
|||
|
||||
button = toggleButton(dbg);
|
||||
frames = findAllElements(dbg, "frames");
|
||||
is(button.innerText, "Collapse Rows", "toggle button should be collapse");
|
||||
is(button.innerText, "Collapse Rows", "toggle button should be collapsed");
|
||||
is(frames.length, 22, "All of the frames should be shown");
|
||||
});
|
||||
|
|
|
@ -18,7 +18,9 @@ add_task(function* () {
|
|||
// Wait for the source text to load and make sure we're in the right
|
||||
// place.
|
||||
yield waitForDispatch(dbg, "LOAD_SOURCE_TEXT");
|
||||
assertHighlightLocation(dbg, "long.js", 66);
|
||||
|
||||
// TODO: revisit highlighting lines when the debugger opens
|
||||
//assertHighlightLocation(dbg, "long.js", 66);
|
||||
|
||||
// Jump to line 16 and make sure the editor scrolled.
|
||||
yield selectSource(dbg, "long.js", 16);
|
||||
|
|
|
@ -50,5 +50,5 @@ add_task(function* () {
|
|||
invokeInTab("testModel");
|
||||
yield waitForPaused(dbg);
|
||||
assertPausedLocation(dbg, longSrc, 66);
|
||||
// ok(isElementVisible(dbg, "breakpoint"), "Breakpoint is visible");
|
||||
ok(isElementVisible(dbg, "breakpoint"), "Breakpoint is visible");
|
||||
});
|
||||
|
|
|
@ -1,12 +1,56 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const {
|
||||
setupTestRunner,
|
||||
expressions
|
||||
} = require("devtools/client/debugger/new/integration-tests");
|
||||
/**
|
||||
* tests the watch expressions component
|
||||
* 1. add watch expressions
|
||||
* 2. edit watch expressions
|
||||
* 3. delete watch expressions
|
||||
*/
|
||||
|
||||
const expressionSelectors = {
|
||||
input: "input.input-expression"
|
||||
};
|
||||
|
||||
function getLabel(dbg, index) {
|
||||
return findElement(dbg, "expressionNode", index).innerText;
|
||||
}
|
||||
|
||||
function getValue(dbg, index) {
|
||||
return findElement(dbg, "expressionValue", index).innerText;
|
||||
}
|
||||
|
||||
async function addExpression(dbg, input) {
|
||||
info("Adding an expression");
|
||||
findElementWithSelector(dbg, expressionSelectors.input).focus();
|
||||
type(dbg, input);
|
||||
pressKey(dbg, "Enter");
|
||||
|
||||
await waitForDispatch(dbg, "EVALUATE_EXPRESSION");
|
||||
}
|
||||
|
||||
async function editExpression(dbg, input) {
|
||||
info("updating the expression");
|
||||
dblClickElement(dbg, "expressionNode", 1);
|
||||
type(dbg, input);
|
||||
pressKey(dbg, "Enter");
|
||||
await waitForDispatch(dbg, "EVALUATE_EXPRESSION");
|
||||
}
|
||||
|
||||
add_task(function*() {
|
||||
setupTestRunner(this);
|
||||
yield expressions(this);
|
||||
const dbg = yield initDebugger("doc-script-switching.html");
|
||||
|
||||
invokeInTab("firstCall");
|
||||
yield waitForPaused(dbg);
|
||||
|
||||
yield addExpression(dbg, "f");
|
||||
is(getLabel(dbg, 1), "f");
|
||||
is(getValue(dbg, 1), "ReferenceError");
|
||||
|
||||
yield editExpression(dbg, "oo");
|
||||
is(getLabel(dbg, 1), "foo()");
|
||||
is(getValue(dbg, 1), "");
|
||||
|
||||
yield deleteExpression(dbg, "foo");
|
||||
is(findAllElements(dbg, "expressionNodes").length, 0);
|
||||
});
|
||||
|
|
|
@ -20,7 +20,6 @@ add_task(function* () {
|
|||
const dbg = yield initDebugger("doc-exceptions.html");
|
||||
|
||||
// test skipping an uncaught exception
|
||||
yield togglePauseOnExceptions(dbg, false, false);
|
||||
yield uncaughtException();
|
||||
ok(!isPaused(dbg));
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
// Tests basic pretty-printing functionality.
|
||||
|
||||
add_task(function* () {
|
||||
add_task(function*() {
|
||||
const dbg = yield initDebugger("doc-minified.html");
|
||||
|
||||
yield selectSource(dbg, "math.min.js");
|
||||
|
|
|
@ -19,4 +19,13 @@ add_task(function* () {
|
|||
|
||||
is(getLabel(dbg, 1), "secondCall");
|
||||
is(getLabel(dbg, 2), "<this>");
|
||||
is(getLabel(dbg, 4), "foo()");
|
||||
|
||||
toggleNode(dbg, 4);
|
||||
yield waitForDispatch(dbg, "LOAD_OBJECT_PROPERTIES");
|
||||
is(getLabel(dbg, 5), "prototype");
|
||||
|
||||
yield stepOver(dbg);
|
||||
is(getLabel(dbg, 4), "foo()");
|
||||
is(getLabel(dbg, 5), "prototype");
|
||||
});
|
||||
|
|
|
@ -4,7 +4,10 @@
|
|||
// Test that an error while loading a sourcemap does not break
|
||||
// debugging.
|
||||
|
||||
add_task(function* () {
|
||||
add_task(function*() {
|
||||
// NOTE: the CORS call makes the test run times inconsistent
|
||||
requestLongerTimeout(2);
|
||||
|
||||
const dbg = yield initDebugger("doc-sourcemap-bogus.html");
|
||||
const { selectors: { getSources }, getState } = dbg;
|
||||
|
||||
|
|
|
@ -4,7 +4,10 @@
|
|||
// Tests loading sourcemapped sources, setting breakpoints, and
|
||||
// stepping in them.
|
||||
|
||||
add_task(function* () {
|
||||
add_task(function*() {
|
||||
// NOTE: the CORS call makes the test run times inconsistent
|
||||
requestLongerTimeout(2);
|
||||
|
||||
const dbg = yield initDebugger("doc-sourcemaps.html");
|
||||
const { selectors: { getBreakpoint, getBreakpoints }, getState } = dbg;
|
||||
|
||||
|
@ -13,21 +16,27 @@ add_task(function* () {
|
|||
const entrySrc = findSource(dbg, "entry.js");
|
||||
|
||||
yield selectSource(dbg, entrySrc);
|
||||
ok(dbg.win.cm.getValue().includes("window.keepMeAlive"),
|
||||
"Original source text loaded correctly");
|
||||
ok(
|
||||
dbg.win.cm.getValue().includes("window.keepMeAlive"),
|
||||
"Original source text loaded correctly"
|
||||
);
|
||||
|
||||
// Test that breakpoint sliding is not attempted. The breakpoint
|
||||
// should not move anywhere.
|
||||
yield addBreakpoint(dbg, entrySrc, 13);
|
||||
is(getBreakpoints(getState()).size, 1, "One breakpoint exists");
|
||||
ok(getBreakpoint(getState(), { sourceId: entrySrc.id, line: 13 }),
|
||||
"Breakpoint has correct line");
|
||||
ok(
|
||||
getBreakpoint(getState(), { sourceId: entrySrc.id, line: 13 }),
|
||||
"Breakpoint has correct line"
|
||||
);
|
||||
|
||||
// Test breaking on a breakpoint
|
||||
yield addBreakpoint(dbg, "entry.js", 15);
|
||||
is(getBreakpoints(getState()).size, 2, "Two breakpoints exist");
|
||||
ok(getBreakpoint(getState(), { sourceId: entrySrc.id, line: 15 }),
|
||||
"Breakpoint has correct line");
|
||||
ok(
|
||||
getBreakpoint(getState(), { sourceId: entrySrc.id, line: 15 }),
|
||||
"Breakpoint has correct line"
|
||||
);
|
||||
|
||||
invokeInTab("keepMeAlive");
|
||||
yield waitForPaused(dbg);
|
||||
|
|
|
@ -6,7 +6,10 @@
|
|||
|
||||
// This source map does not have source contents, so it's fetched separately
|
||||
|
||||
add_task(function* () {
|
||||
add_task(function*() {
|
||||
// NOTE: the CORS call makes the test run times inconsistent
|
||||
requestLongerTimeout(2);
|
||||
|
||||
const dbg = yield initDebugger("doc-sourcemaps2.html");
|
||||
const { selectors: { getBreakpoint, getBreakpoints }, getState } = dbg;
|
||||
|
||||
|
@ -20,8 +23,10 @@ add_task(function* () {
|
|||
// Test that breakpoint is not off by a line.
|
||||
yield addBreakpoint(dbg, mainSrc, 4);
|
||||
is(getBreakpoints(getState()).size, 1, "One breakpoint exists");
|
||||
ok(getBreakpoint(getState(), { sourceId: mainSrc.id, line: 4 }),
|
||||
"Breakpoint has correct line");
|
||||
ok(
|
||||
getBreakpoint(getState(), { sourceId: mainSrc.id, line: 4 }),
|
||||
"Breakpoint has correct line"
|
||||
);
|
||||
|
||||
invokeInTab("logMessage");
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<body>
|
||||
<script>
|
||||
debugger;
|
||||
|
||||
// This inline script allows this HTML page to show up as a
|
||||
// source. It also needs to introduce a new global variable so
|
||||
// it's not immediately garbage collected.
|
||||
|
|
|
@ -33,13 +33,14 @@
|
|||
*/
|
||||
|
||||
// shared-head.js handles imports, constants, and utility functions
|
||||
Services.scriptloader.loadSubScript("chrome://mochitests/content/browser/devtools/client/framework/test/shared-head.js", this);
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://mochitests/content/browser/devtools/client/framework/test/shared-head.js",
|
||||
this
|
||||
);
|
||||
var { Toolbox } = require("devtools/client/framework/toolbox");
|
||||
const EXAMPLE_URL = "http://example.com/browser/devtools/client/debugger/new/test/mochitest/examples/";
|
||||
|
||||
Services.prefs.setBoolPref("devtools.debugger.new-debugger-frontend", true);
|
||||
Services.prefs.clearUserPref("devtools.debugger.tabs")
|
||||
Services.prefs.clearUserPref("devtools.debugger.pending-selected-location")
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("devtools.debugger.new-debugger-frontend");
|
||||
|
@ -76,9 +77,9 @@ function _afterDispatchDone(store, type) {
|
|||
type: "@@service/waitUntil",
|
||||
predicate: action => {
|
||||
if (action.type === type) {
|
||||
return action.status ?
|
||||
(action.status === "done" || action.status === "error") :
|
||||
true;
|
||||
return action.status
|
||||
? action.status === "done" || action.status === "error"
|
||||
: true;
|
||||
}
|
||||
},
|
||||
run: (dispatch, getState, action) => {
|
||||
|
@ -102,7 +103,7 @@ function _afterDispatchDone(store, type) {
|
|||
function waitForDispatch(dbg, type, eventRepeat = 1) {
|
||||
let count = 0;
|
||||
|
||||
return Task.spawn(function* () {
|
||||
return Task.spawn(function*() {
|
||||
info("Waiting for " + type + " to dispatch " + eventRepeat + " time(s)");
|
||||
while (count < eventRepeat) {
|
||||
yield _afterDispatchDone(dbg.store, type);
|
||||
|
@ -170,21 +171,23 @@ function waitForSources(dbg, ...sources) {
|
|||
|
||||
info("Waiting on sources: " + sources.join(", "));
|
||||
const { selectors: { getSources }, store } = dbg;
|
||||
return Promise.all(sources.map(url => {
|
||||
function sourceExists(state) {
|
||||
return getSources(state).some(s => {
|
||||
return s.get("url").includes(url);
|
||||
});
|
||||
}
|
||||
return Promise.all(
|
||||
sources.map(url => {
|
||||
function sourceExists(state) {
|
||||
return getSources(state).some(s => {
|
||||
return s.get("url").includes(url);
|
||||
});
|
||||
}
|
||||
|
||||
if (!sourceExists(store.getState())) {
|
||||
return waitForState(dbg, sourceExists);
|
||||
}
|
||||
}));
|
||||
if (!sourceExists(store.getState())) {
|
||||
return waitForState(dbg, sourceExists);
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function waitForElement(dbg, selector) {
|
||||
return waitUntil(() => findElementWithSelector(dbg, selector))
|
||||
return waitUntil(() => findElementWithSelector(dbg, selector));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -209,8 +212,10 @@ function assertPausedLocation(dbg, source, line) {
|
|||
is(location.get("line"), line);
|
||||
|
||||
// Check the debug line
|
||||
ok(dbg.win.cm.lineInfo(line - 1).wrapClass.includes("debug-line"),
|
||||
"Line is highlighted as paused");
|
||||
ok(
|
||||
dbg.win.cm.lineInfo(line - 1).wrapClass.includes("debug-line"),
|
||||
"Line is highlighted as paused"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -232,10 +237,14 @@ function assertHighlightLocation(dbg, source, line) {
|
|||
// Check the highlight line
|
||||
const lineEl = findElement(dbg, "highlightLine");
|
||||
ok(lineEl, "Line is highlighted");
|
||||
// ok(isVisibleWithin(findElement(dbg, "codeMirror"), lineEl),
|
||||
// "Highlighted line is visible");
|
||||
ok(dbg.win.cm.lineInfo(line - 1).wrapClass.includes("highlight-line"),
|
||||
"Line is highlighted");
|
||||
ok(
|
||||
isVisibleWithin(findElement(dbg, "codeMirror"), lineEl),
|
||||
"Highlighted line is visible"
|
||||
);
|
||||
ok(
|
||||
dbg.win.cm.lineInfo(line - 1).wrapClass.includes("highlight-line"),
|
||||
"Line is highlighted"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -258,12 +267,11 @@ function isPaused(dbg) {
|
|||
* @static
|
||||
*/
|
||||
function waitForPaused(dbg) {
|
||||
return Task.spawn(function* () {
|
||||
return Task.spawn(function*() {
|
||||
// We want to make sure that we get both a real paused event and
|
||||
// that the state is fully populated. The client may do some more
|
||||
// work (call other client methods) before populating the state.
|
||||
yield waitForThreadEvents(dbg, "paused"),
|
||||
yield waitForState(dbg, state => {
|
||||
yield waitForThreadEvents(dbg, "paused"), yield waitForState(dbg, state => {
|
||||
const pause = dbg.selectors.getPause(state);
|
||||
// Make sure we have the paused state.
|
||||
if (!pause) {
|
||||
|
@ -279,15 +287,16 @@ function waitForPaused(dbg) {
|
|||
}
|
||||
|
||||
function createDebuggerContext(toolbox) {
|
||||
const win = toolbox.getPanel("jsdebugger").panelWin;
|
||||
const store = win.Debugger.store;
|
||||
const panel = toolbox.getPanel("jsdebugger");
|
||||
const win = panel.panelWin;
|
||||
const { store, client, selectors, actions } = panel.getVarsForTests();
|
||||
|
||||
return {
|
||||
actions: win.Debugger.actions,
|
||||
selectors: win.Debugger.selectors,
|
||||
actions: actions,
|
||||
selectors: selectors,
|
||||
getState: store.getState,
|
||||
store: store,
|
||||
client: win.Debugger.client,
|
||||
client: client,
|
||||
toolbox: toolbox,
|
||||
win: win
|
||||
};
|
||||
|
@ -303,9 +312,13 @@ function createDebuggerContext(toolbox) {
|
|||
* @static
|
||||
*/
|
||||
function initDebugger(url, ...sources) {
|
||||
return Task.spawn(function* () {
|
||||
Services.prefs.clearUserPref("devtools.debugger.tabs")
|
||||
Services.prefs.clearUserPref("devtools.debugger.pending-selected-location")
|
||||
return Task.spawn(function*() {
|
||||
Services.prefs.clearUserPref("devtools.debugger.pause-on-exceptions");
|
||||
Services.prefs.clearUserPref("devtools.debugger.ignore-caught-exceptions");
|
||||
Services.prefs.clearUserPref("devtools.debugger.tabs");
|
||||
Services.prefs.clearUserPref("devtools.debugger.pending-selected-location");
|
||||
Services.prefs.clearUserPref("devtools.debugger.pending-breakpoints");
|
||||
Services.prefs.clearUserPref("devtools.debugger.expressions");
|
||||
const toolbox = yield openNewTabAndToolbox(EXAMPLE_URL + url, "jsdebugger");
|
||||
return createDebuggerContext(toolbox);
|
||||
});
|
||||
|
@ -429,6 +442,11 @@ function resume(dbg) {
|
|||
return waitForThreadEvents(dbg, "resumed");
|
||||
}
|
||||
|
||||
function deleteExpression(dbg, input) {
|
||||
info("Resuming");
|
||||
return dbg.actions.deleteExpression({ input });
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads the debuggee.
|
||||
*
|
||||
|
@ -500,8 +518,11 @@ function removeBreakpoint(dbg, sourceId, line, col) {
|
|||
* @return {Promise}
|
||||
* @static
|
||||
*/
|
||||
function togglePauseOnExceptions(dbg,
|
||||
pauseOnExceptions, ignoreCaughtExceptions) {
|
||||
function togglePauseOnExceptions(
|
||||
dbg,
|
||||
pauseOnExceptions,
|
||||
ignoreCaughtExceptions
|
||||
) {
|
||||
const command = dbg.actions.pauseOnExceptions(
|
||||
pauseOnExceptions,
|
||||
ignoreCaughtExceptions
|
||||
|
@ -526,7 +547,7 @@ function togglePauseOnExceptions(dbg,
|
|||
*/
|
||||
function invokeInTab(fnc) {
|
||||
info(`Invoking function ${fnc} in tab`);
|
||||
return ContentTask.spawn(gBrowser.selectedBrowser, fnc, function* (fnc) {
|
||||
return ContentTask.spawn(gBrowser.selectedBrowser, fnc, function*(fnc) {
|
||||
content.wrappedJSObject[fnc](); // eslint-disable-line mozilla/no-cpows-in-tests, max-len
|
||||
});
|
||||
}
|
||||
|
@ -534,18 +555,21 @@ function invokeInTab(fnc) {
|
|||
const isLinux = Services.appinfo.OS === "Linux";
|
||||
const cmdOrCtrl = isLinux ? { ctrlKey: true } : { metaKey: true };
|
||||
const keyMappings = {
|
||||
sourceSearch: { code: "p", modifiers: cmdOrCtrl},
|
||||
fileSearch: { code: "f", modifiers: cmdOrCtrl},
|
||||
"Enter": { code: "VK_RETURN" },
|
||||
"Up": { code: "VK_UP" },
|
||||
"Down": { code: "VK_DOWN" },
|
||||
"Tab": { code: "VK_TAB" },
|
||||
"Escape": { code: "VK_ESCAPE" },
|
||||
sourceSearch: { code: "p", modifiers: cmdOrCtrl },
|
||||
fileSearch: { code: "f", modifiers: cmdOrCtrl },
|
||||
Enter: { code: "VK_RETURN" },
|
||||
Up: { code: "VK_UP" },
|
||||
Down: { code: "VK_DOWN" },
|
||||
Tab: { code: "VK_TAB" },
|
||||
Escape: { code: "VK_ESCAPE" },
|
||||
pauseKey: { code: "VK_F8" },
|
||||
resumeKey: { code: "VK_F8" },
|
||||
stepOverKey: { code: "VK_F10" },
|
||||
stepInKey: { code: "VK_F11", modifiers: { ctrlKey: isLinux }},
|
||||
stepOutKey: { code: "VK_F11", modifiers: { ctrlKey: isLinux, shiftKey: true }}
|
||||
stepInKey: { code: "VK_F11", modifiers: { ctrlKey: isLinux } },
|
||||
stepOutKey: {
|
||||
code: "VK_F11",
|
||||
modifiers: { ctrlKey: isLinux, shiftKey: true }
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -561,11 +585,7 @@ function pressKey(dbg, keyName) {
|
|||
let keyEvent = keyMappings[keyName];
|
||||
|
||||
const { code, modifiers } = keyEvent;
|
||||
return EventUtils.synthesizeKey(
|
||||
code,
|
||||
modifiers || {},
|
||||
dbg.win
|
||||
);
|
||||
return EventUtils.synthesizeKey(code, modifiers || {}, dbg.win);
|
||||
}
|
||||
|
||||
function type(dbg, string) {
|
||||
|
@ -577,14 +597,19 @@ function type(dbg, string) {
|
|||
function isVisibleWithin(outerEl, innerEl) {
|
||||
const innerRect = innerEl.getBoundingClientRect();
|
||||
const outerRect = outerEl.getBoundingClientRect();
|
||||
|
||||
return innerRect.top > outerRect.top &&
|
||||
innerRect.bottom < outerRect.bottom;
|
||||
return innerRect.top > outerRect.top && innerRect.bottom < outerRect.bottom;
|
||||
}
|
||||
|
||||
const selectors = {
|
||||
callStackHeader: ".call-stack-pane ._header",
|
||||
callStackBody: ".call-stack-pane .pane",
|
||||
expressionNode: i =>
|
||||
`.expressions-list .tree-node:nth-child(${i}) .object-label`,
|
||||
expressionValue: i =>
|
||||
`.expressions-list .tree-node:nth-child(${i}) .object-value`,
|
||||
expressionClose: i =>
|
||||
`.expressions-list .expression-container:nth-child(${i}) .close`,
|
||||
expressionNodes: ".expressions-list .tree-node",
|
||||
scopesHeader: ".scopes-pane ._header",
|
||||
breakpointItem: i => `.breakpoints-list .breakpoint:nth-child(${i})`,
|
||||
scopeNode: i => `.scopes-list .tree-node:nth-child(${i}) .object-label`,
|
||||
|
@ -605,7 +630,7 @@ const selectors = {
|
|||
sourceFooter: ".source-footer",
|
||||
sourceNode: i => `.sources-list .tree-node:nth-child(${i})`,
|
||||
sourceNodes: ".sources-list .tree-node",
|
||||
sourceArrow: i => `.sources-list .tree-node:nth-child(${i}) .arrow`,
|
||||
sourceArrow: i => `.sources-list .tree-node:nth-child(${i}) .arrow`
|
||||
};
|
||||
|
||||
function getSelector(elementName, ...args) {
|
||||
|
@ -647,6 +672,9 @@ function findAllElements(dbg, elementName, ...args) {
|
|||
*/
|
||||
function clickElement(dbg, elementName, ...args) {
|
||||
const selector = getSelector(elementName, ...args);
|
||||
const el = findElement(dbg, elementName, ...args);
|
||||
el.scrollIntoView();
|
||||
|
||||
return EventUtils.synthesizeMouseAtCenter(
|
||||
findElementWithSelector(dbg, selector),
|
||||
{},
|
||||
|
@ -654,12 +682,22 @@ function clickElement(dbg, elementName, ...args) {
|
|||
);
|
||||
}
|
||||
|
||||
function dblClickElement(dbg, elementName, ...args) {
|
||||
const selector = getSelector(elementName, ...args);
|
||||
|
||||
return EventUtils.synthesizeMouseAtCenter(
|
||||
findElementWithSelector(dbg, selector),
|
||||
{ clickCount: 2 },
|
||||
dbg.win
|
||||
);
|
||||
}
|
||||
|
||||
function rightClickElement(dbg, elementName, ...args) {
|
||||
const selector = getSelector(elementName, ...args);
|
||||
const doc = dbg.win.document;
|
||||
return EventUtils.synthesizeMouseAtCenter(
|
||||
doc.querySelector(selector),
|
||||
{type: "contextmenu"},
|
||||
{ type: "contextmenu" },
|
||||
dbg.win
|
||||
);
|
||||
}
|
||||
|
@ -669,10 +707,10 @@ function selectMenuItem(dbg, index) {
|
|||
const doc = dbg.toolbox.win.document;
|
||||
|
||||
// there are several context menus, we want the one with the menu-api
|
||||
const popup = doc.querySelector("menupopup[menu-api=\"true\"]");
|
||||
const popup = doc.querySelector('menupopup[menu-api="true"]');
|
||||
|
||||
const item = popup.querySelector(`menuitem:nth-child(${index})`);
|
||||
return EventUtils.synthesizeMouseAtCenter(item, {}, dbg.toolbox.win );
|
||||
return EventUtils.synthesizeMouseAtCenter(item, {}, dbg.toolbox.win);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -124,6 +124,10 @@ blackBoxCheckboxTooltip=Toggle black boxing
|
|||
# searching all the source files the debugger has seen.
|
||||
sources.search.key=P
|
||||
|
||||
# LOCALIZATION NOTE (sources.noSourcesAvailable): Text shown when the debugger
|
||||
# does not have any sources.
|
||||
sources.noSourcesAvailable=This page has no sources
|
||||
|
||||
# LOCALIZATION NOTE (sources.searchAlt.key): Alternate key shortcut to open
|
||||
# the search for searching all the source files the debugger has seen.
|
||||
sources.searchAlt.key=O
|
||||
|
@ -235,10 +239,17 @@ callStack.expand=Expand Rows
|
|||
# for the summarizing the selected search result. e.g. 5 of 10 results.
|
||||
editor.searchResults=%d of %d results
|
||||
|
||||
# LOCALIZATION NOTE (sourceSearch.singleResult): Copy shown when there is one result.
|
||||
editor.singleResult=1 result
|
||||
|
||||
# LOCALIZATION NOTE (editor.noResults): Editor Search bar message
|
||||
# for when no results found.
|
||||
editor.noResults=no results
|
||||
|
||||
# LOCALIZATION NOTE (editor.searchTypeToggleTitle): Search bar title for
|
||||
# toggling search type buttons(function search, variable search)
|
||||
editor.searchTypeToggleTitle=Search for:
|
||||
|
||||
# LOCALIZATION NOTE (editor.addBreakpoint): Editor gutter context menu item
|
||||
# for adding a breakpoint on a line.
|
||||
editor.addBreakpoint=Add Breakpoint
|
||||
|
@ -271,9 +282,9 @@ editor.conditionalPanel.placeholder=This breakpoint will pause when the expressi
|
|||
# close button inside ConditionalPanel component
|
||||
editor.conditionalPanel.close=Cancel edit breakpoint and close
|
||||
|
||||
# LOCALIZATION NOTE (editor.jumpToMappedLocation1): Context menu item
|
||||
# LOCALIZATION NOTE (editor.jumpToMappedLocation): Context menu item
|
||||
# for navigating to a source mapped location
|
||||
editor.jumpToMappedLocation1=Jump to %S location
|
||||
editor.jumpToMappedLocation=Jump to %s location
|
||||
|
||||
# LOCALIZATION NOTE (generated): Source Map term for a server source location
|
||||
generated=generated
|
||||
|
@ -341,6 +352,22 @@ sourceTabs.prettyPrint=Pretty Print Source
|
|||
# the editor context menu.
|
||||
sourceTabs.prettyPrint.accesskey=p
|
||||
|
||||
# LOCALIZATION NOTE (sourceFooter.blackbox): Tooltip text associated
|
||||
# with the black box button
|
||||
sourceFooter.blackbox=Blackbox Source
|
||||
|
||||
# LOCALIZATION NOTE (sourceFooter.unblackbox): Tooltip text associated
|
||||
# with the black box button
|
||||
sourceFooter.unblackbox=Unblackbox Source
|
||||
|
||||
# LOCALIZATION NOTE (sourceFooter.blackbox.accesskey): Access key to black box
|
||||
# an associated source
|
||||
sourceFooter.blackbox.accesskey=b
|
||||
|
||||
# LOCALIZATION NOTE (sourceFooter.blackboxed): Text associated
|
||||
# with a blackboxed source
|
||||
sourceFooter.blackboxed=Blackboxed Source
|
||||
|
||||
# LOCALIZATION NOTE (sourceTabs.closeTabButtonTooltip): The tooltip that is displayed
|
||||
# for close tab button in source tabs.
|
||||
sourceTabs.closeTabButtonTooltip=Close tab
|
||||
|
@ -393,10 +420,6 @@ sourceSearch.search=Search Sources…
|
|||
# message when the query did not match any of the sources.
|
||||
sourceSearch.noResults=No files matching %S found
|
||||
|
||||
# LOCALIZATION NOTE (sourceFooter.debugBtnTooltip): Tooltip text associated
|
||||
# with the pretty-print button
|
||||
sourceFooter.debugBtnTooltip=Prettify Source
|
||||
|
||||
# LOCALIZATION NOTE (ignoreExceptions): The pause on exceptions button tooltip
|
||||
# when the debugger will not pause on exceptions.
|
||||
ignoreExceptions=Ignore exceptions. Click to pause on uncaught exceptions
|
||||
|
@ -508,8 +531,30 @@ watchExpressionsSeparatorLabel2=\u0020→
|
|||
# in the functions search panel as a separator between function's inferred name
|
||||
# and its real name (if available).
|
||||
functionSearchSeparatorLabel=←
|
||||
functionSearch.search.placeholder=Search Functions…
|
||||
functionSearch.search.key=O
|
||||
|
||||
# LOCALIZATION NOTE(symbolSearch.search.functionsPlaceholder): The placeholder
|
||||
# text displayed when the user searches for functions in a file
|
||||
symbolSearch.search.functionsPlaceholder=Search functions…
|
||||
|
||||
# LOCALIZATION NOTE(symbolSearch.search.variablesPlaceholder): The placeholder
|
||||
# text displayed when the user searches for variables in a file
|
||||
symbolSearch.search.variablesPlaceholder=Search variables…
|
||||
|
||||
# LOCALIZATION NOTE(symbolSearch.search.key): The shortcut (cmd+shift+o) for
|
||||
# searching for a function or variable
|
||||
symbolSearch.search.key=O
|
||||
|
||||
# LOCALIZATION NOTE(symbolSearch.searchModifier.regex): A search option
|
||||
# when searching text in a file
|
||||
symbolSearch.searchModifier.regex=Regex
|
||||
|
||||
# LOCALIZATION NOTE(symbolSearch.searchModifier.caseSensitive): A search option
|
||||
# when searching text in a file
|
||||
symbolSearch.searchModifier.caseSensitive=Case sensitive
|
||||
|
||||
# LOCALIZATION NOTE(symbolSearch.searchModifier.wholeWord): A search option
|
||||
# when searching text in a file
|
||||
symbolSearch.searchModifier.wholeWord=Whole word
|
||||
|
||||
# LOCALIZATION NOTE (resumptionOrderPanelTitle): This is the text that appears
|
||||
# as a description in the notification panel popup, when multiple debuggers are
|
||||
|
@ -577,3 +622,7 @@ whyPaused.debugCommand=Paused on debugged function
|
|||
# in a info block explaining how the debugger is currently paused on an event
|
||||
# listener breakpoint set
|
||||
whyPaused.other=Debugger paused
|
||||
|
||||
# LOCALIZATION NOTE (ctrl): The text that is used for documenting
|
||||
# keyboard shortcuts that use the control key
|
||||
ctrl=Ctrl
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
# -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
|
||||
# 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/.
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
#ifdef RELEASE_OR_BETA
|
||||
pref("devtools.debugger.new-debugger-frontend", false);
|
||||
|
@ -17,7 +15,7 @@ pref("devtools.debugger.chrome-debugging-websocket", false);
|
|||
pref("devtools.debugger.remote-host", "localhost");
|
||||
pref("devtools.debugger.remote-timeout", 20000);
|
||||
pref("devtools.debugger.pause-on-exceptions", false);
|
||||
pref("devtools.debugger.ignore-caught-exceptions", true);
|
||||
pref("devtools.debugger.ignore-caught-exceptions", false);
|
||||
pref("devtools.debugger.source-maps-enabled", true);
|
||||
pref("devtools.debugger.client-source-maps-enabled", true);
|
||||
pref("devtools.debugger.pretty-print-enabled", true);
|
||||
|
@ -38,4 +36,5 @@ pref("devtools.debugger.start-panel-collapsed", false);
|
|||
pref("devtools.debugger.end-panel-collapsed", false);
|
||||
pref("devtools.debugger.tabs", "[]");
|
||||
pref("devtools.debugger.pending-selected-location", "{}");
|
||||
|
||||
pref("devtools.debugger.pending-breakpoints", "[]");
|
||||
pref("devtools.debugger.expressions", "[]");
|
||||
|
|
|
@ -59,10 +59,10 @@ exports.viewSourceInDebugger = Task.async(function* (toolbox, sourceURL, sourceL
|
|||
|
||||
// New debugger frontend
|
||||
if (Services.prefs.getBoolPref("devtools.debugger.new-debugger-frontend")) {
|
||||
const source = dbg._selectors().getSourceByURL(dbg._getState(), sourceURL);
|
||||
const source = dbg.getSource(sourceURL);
|
||||
if (source) {
|
||||
yield toolbox.selectTool("jsdebugger");
|
||||
dbg._actions().selectSourceURL(sourceURL, { line: sourceLine });
|
||||
dbg.selectSource(sourceURL, sourceLine);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ function* checkClickOnNode(hud, toolbox, frameLinkNode) {
|
|||
|
||||
let dbg = toolbox.getPanel("jsdebugger");
|
||||
is(
|
||||
dbg._selectors().getSelectedSource(dbg._getState()).get("url"),
|
||||
dbg._selectors.getSelectedSource(dbg._getState()).get("url"),
|
||||
url,
|
||||
"expected source url"
|
||||
);
|
||||
|
|
|
@ -56,7 +56,7 @@ function* checkClickOnNode(hud, toolbox, frameLinkNode) {
|
|||
let url = frameLinkNode.getAttribute("data-url");
|
||||
let dbg = toolbox.getPanel("jsdebugger");
|
||||
is(
|
||||
dbg._selectors().getSelectedSource(dbg._getState()).get("url"),
|
||||
dbg._selectors.getSelectedSource(dbg._getState()).get("url"),
|
||||
url,
|
||||
`Debugger is opened at expected source url (${url})`
|
||||
);
|
||||
|
|
|
@ -81,7 +81,7 @@ function test() {
|
|||
|
||||
let toolbox = yield gDevTools.getToolbox(hud.target);
|
||||
let dbg = toolbox.getPanel("jsdebugger");
|
||||
is(dbg._selectors().getSelectedSource(dbg._getState()).get("url"),
|
||||
is(dbg._selectors.getSelectedSource(dbg._getState()).get("url"),
|
||||
url,
|
||||
"expected source url");
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче