Bug 1354672 - update debugger frontend 04/18/17;r=jdescottes

MozReview-Commit-ID: HI2NymoCLYR

--HG--
extra : rebase_source : 76cd533614d04771319f484cf8eb642d5f966e75
This commit is contained in:
Julian Descottes 2017-04-18 10:25:19 +02:00
Родитель a3cb362804
Коммит ef9a9e80c9
26 изменённых файлов: 67188 добавлений и 58191 удалений

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -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");
}