Bug 1500998 - Update debugger frontend v94 r=jdescottes

This commit is contained in:
David Walsh 2018-10-22 16:00:28 -05:00
Родитель 44a3847f77
Коммит b9e4308d69
22 изменённых файлов: 448 добавлений и 1991 удалений

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

@ -1,9 +1,9 @@
This is the debugger.html project output.
See https://github.com/devtools-html/debugger.html
Version 92
Version 94
Comparison: https://github.com/devtools-html/debugger.html/compare/release-91...release-92
Comparison: https://github.com/devtools-html/debugger.html/compare/release-93...release-94
Packages:
- babel-plugin-transform-es2015-modules-commonjs @6.26.2

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

@ -1364,7 +1364,8 @@ html .toggle-button.end.vertical svg {
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
.search-shadow {
border: 1px solid transparent;
border: 1px solid var(--theme-toolbar-background);
border-bottom: 1px solid var(--theme-splitter-color);
}
.search-shadow.focused {
@ -1595,6 +1596,8 @@ html .toggle-button.end.vertical svg {
display: flex;
align-self: stretch;
flex-grow: 1;
width: 100%;
border-bottom: none;
}
.project-text-search .search-field .close-btn.big {
@ -2000,6 +2003,30 @@ menuseparator {
height: 100%;
z-index: 999;
}
.outline-filter {
margin: 5px 0 0 0;
padding: 0px 10px;
}
.outline-filter-input {
padding: 0.5em 1.6em;
width: 100%;
border: 1px solid var(--theme-splitter-color);
background-color: var(--theme-sidebar-background);
color: var(--theme-body-color);
font-size: 12px;
-moz-user-select: text;
user-select: text;
}
.outline-filter-input.focused {
border: 1px solid var(--theme-highlight-blue);
}
.outline-filter-input::placeholder {
font-style: italic;
color: var(--theme-comment);
}
/* 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/>. */
@ -2014,32 +2041,32 @@ menuseparator {
}
.outline-pane-info {
padding: 0.5em;
width: 100%;
font-style: italic;
text-align: center;
padding: 0.5em;
user-select: none;
font-size: 12px;
overflow: hidden;
}
.outline-list {
list-style-type: none;
padding: 4px 0;
margin: 0;
padding: 0 0 4px 0;
position: absolute;
top: 38px;
bottom: 25px;
left: 0;
right: 0;
list-style-type: none;
font-family: var(--monospace-font-family);
overflow: auto;
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 25px;
}
.outline-list__class-list {
list-style: none;
margin: 0;
padding: 0;
list-style: none;
}
.outline-list__class-list .function-signature .function-name {
@ -2051,9 +2078,9 @@ menuseparator {
}
.outline-list h2 {
margin: 10px 0 10px 10px;
font-weight: normal;
font-size: 1em;
margin: 10px 0 10px 10px;
color: var(--blue-55);
}
@ -2085,19 +2112,19 @@ menuseparator {
}
.outline-footer {
background: var(--theme-body-background);
border-top: 1px solid var(--theme-splitter-color);
display: flex;
box-sizing: border-box;
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 25px;
background: var(--theme-body-background);
border-top: 1px solid var(--theme-splitter-color);
opacity: 1;
z-index: 1;
-moz-user-select: none;
user-select: none;
height: 25px;
box-sizing: border-box;
display: flex;
}
.theme-dark .outline-footer button {
@ -2298,6 +2325,7 @@ menuseparator {
.search-bar .search-shadow {
flex-grow: 1;
border-bottom: none;
}
.search-bar .search-shadow.focused {

1900
devtools/client/debugger/new/dist/vendors.js поставляемый

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

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

@ -27,26 +27,30 @@ var _selectors = require("../selectors/index");
*/
function updateTab(source, framework) {
const {
url
url,
id: sourceId
} = source;
const isOriginal = (0, _devtoolsSourceMap.isOriginalId)(source.id);
return {
type: "UPDATE_TAB",
url,
framework,
isOriginal
isOriginal,
sourceId
};
}
function addTab(source) {
const {
url
url,
id: sourceId
} = source;
const isOriginal = (0, _devtoolsSourceMap.isOriginalId)(source.id);
return {
type: "ADD_TAB",
url,
isOriginal
isOriginal,
sourceId
};
}

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

@ -102,7 +102,7 @@ function getMenuItems(event, {
id: "node-menu-copy-source-url",
label: copySourceUri2Label,
accesskey: copySourceUri2Key,
disabled: false,
disabled: !selectedSource.url,
click: () => (0, _clipboard.copyToTheClipboard)((0, _source.getRawSourceURL)(selectedSource.url))
};
const sourceId = selectedSource.id;
@ -139,14 +139,14 @@ function getMenuItems(event, {
id: "node-menu-show-source",
label: revealInTreeLabel,
accesskey: revealInTreeKey,
disabled: false,
disabled: !selectedSource.url,
click: () => showSource(sourceId)
};
const blackBoxMenuItem = {
id: "node-menu-blackbox",
label: toggleBlackBoxLabel,
accesskey: blackboxKey,
disabled: isOriginal || isPrettyPrinted || hasSourceMap,
disabled: isOriginal || isPrettyPrinted || hasSourceMap || !selectedSource.url,
click: () => toggleBlackBox(selectedSource)
};
const watchExpressionItem = {

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

@ -101,14 +101,15 @@ class Tab extends _react.PureComponent {
}
}, {
item: { ...tabMenuItems.copySourceUri2,
disabled: !selectedSource.url,
click: () => (0, _clipboard.copyToTheClipboard)((0, _source.getRawSourceURL)(sourceTab.url))
}
}];
items.push({
}, {
item: { ...tabMenuItems.showSource,
disabled: !selectedSource.url,
click: () => showSource(tab)
}
});
}];
if (!isPrettySource) {
items.push({

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

@ -13,6 +13,8 @@ var _devtoolsContextmenu = require("devtools/client/debugger/new/dist/vendors").
var _reactRedux = require("devtools/client/shared/vendor/react-redux");
var _fuzzaldrinPlus = require("devtools/client/debugger/new/dist/vendors").vendored["fuzzaldrin-plus"];
var _clipboard = require("../../utils/clipboard");
var _function = require("../../utils/function");
@ -23,6 +25,10 @@ var _actions2 = _interopRequireDefault(_actions);
var _selectors = require("../../selectors/index");
var _OutlineFilter = require("./OutlineFilter");
var _OutlineFilter2 = _interopRequireDefault(_OutlineFilter);
var _PreviewFunction = require("../shared/PreviewFunction");
var _PreviewFunction2 = _interopRequireDefault(_PreviewFunction);
@ -34,7 +40,35 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
/* 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/>. */
/**
* Check whether the name argument matches the fuzzy filter argument
*/
const filterOutlineItem = (name, filter) => {
// Set higher to make the fuzzaldrin filter more specific
const FUZZALDRIN_FILTER_THRESHOLD = 15000;
if (!filter) {
return true;
}
if (filter.length === 1) {
// when filter is a single char just check if it starts with the char
return filter.toLowerCase() === name.toLowerCase()[0];
}
return (0, _fuzzaldrinPlus.score)(name, filter) > FUZZALDRIN_FILTER_THRESHOLD;
};
class Outline extends _react.Component {
constructor(props) {
super(props);
this.updateFilter = this.updateFilter.bind(this);
this.state = {
filter: ""
};
}
selectItem(location) {
const {
selectedSource,
@ -89,6 +123,12 @@ class Outline extends _react.Component {
(0, _devtoolsContextmenu.showMenu)(event, menuOptions);
}
updateFilter(filter) {
this.setState({
filter: filter.trim()
});
}
renderPlaceholder() {
const placeholderMessage = this.props.selectedSource ? L10N.getStr("outline.noFunctions") : L10N.getStr("outline.noFileSelected");
return _react2.default.createElement("div", {
@ -145,9 +185,12 @@ class Outline extends _react.Component {
}
renderFunctions(functions) {
const {
filter
} = this.state;
let classes = (0, _lodash.uniq)(functions.map(func => func.klass));
let namedFunctions = functions.filter(func => func.name != "anonymous" && !func.klass && !classes.includes(func.name));
let classFunctions = functions.filter(func => func.name != "anonymous" && !!func.klass);
let namedFunctions = functions.filter(func => filterOutlineItem(func.name, filter) && !func.klass && !classes.includes(func.name));
let classFunctions = functions.filter(func => filterOutlineItem(func.name, filter) && !!func.klass);
if (this.props.alphabetizeOutline) {
namedFunctions = (0, _lodash.sortBy)(namedFunctions, "name");
@ -155,16 +198,18 @@ class Outline extends _react.Component {
classFunctions = (0, _lodash.sortBy)(classFunctions, "name");
}
return _react2.default.createElement("div", null, _react2.default.createElement("ul", {
return _react2.default.createElement("ul", {
className: "outline-list"
}, namedFunctions.map(func => this.renderFunction(func)), classes.map(klass => this.renderClassFunctions(klass, classFunctions))), _react2.default.createElement("div", {
}, namedFunctions.map(func => this.renderFunction(func)), classes.map(klass => this.renderClassFunctions(klass, classFunctions)));
}
renderFooter() {
return _react2.default.createElement("div", {
className: "outline-footer bottom"
}, _react2.default.createElement("button", {
onClick: () => {
this.props.onAlphabetizeClick();
},
onClick: this.props.onAlphabetizeClick,
className: this.props.alphabetizeOutline ? "active" : ""
}, L10N.getStr("outline.sortLabel"))));
}, L10N.getStr("outline.sortLabel")));
}
render() {
@ -172,6 +217,9 @@ class Outline extends _react.Component {
symbols,
selectedSource
} = this.props;
const {
filter
} = this.state;
if (!selectedSource) {
return this.renderPlaceholder();
@ -182,9 +230,17 @@ class Outline extends _react.Component {
}
const symbolsToDisplay = symbols.functions.filter(func => func.name != "anonymous");
if (symbolsToDisplay.length === 0) {
return this.renderPlaceholder();
}
return _react2.default.createElement("div", {
className: "outline"
}, symbolsToDisplay.length > 0 ? this.renderFunctions(symbols.functions) : this.renderPlaceholder());
}, _react2.default.createElement("div", null, _react2.default.createElement(_OutlineFilter2.default, {
filter: filter,
updateFilter: this.updateFilter
}), this.renderFunctions(symbolsToDisplay), this.renderFooter()));
}
}

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

@ -0,0 +1,64 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _react = require("devtools/client/shared/vendor/react");
var _react2 = _interopRequireDefault(_react);
var _classnames = require("devtools/client/debugger/new/dist/vendors").vendored["classnames"];
var _classnames2 = _interopRequireDefault(_classnames);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* 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/>. */
class OutlineFilter extends _react.Component {
constructor(...args) {
var _temp;
return _temp = super(...args), this.state = {
focused: false
}, this.setFocus = shouldFocus => {
this.setState({
focused: shouldFocus
});
}, this.onChange = e => {
this.props.updateFilter(e.target.value);
}, this.onKeyDown = e => {
if (e.key === "Escape" && this.props.filter !== "") {
// use preventDefault to override toggling the split-console which is
// also bound to the ESC key
e.preventDefault();
this.props.updateFilter("");
}
}, _temp;
}
render() {
const {
focused
} = this.state;
return _react2.default.createElement("div", {
className: "outline-filter"
}, _react2.default.createElement("form", null, _react2.default.createElement("input", {
className: (0, _classnames2.default)("outline-filter-input", {
focused
}),
onFocus: () => this.setFocus(true),
onBlur: () => this.setFocus(false),
placeholder: L10N.getStr("outline.placeholder"),
value: this.props.filter,
type: "text",
onChange: this.onChange,
onKeyDown: this.onKeyDown
})));
}
}
exports.default = OutlineFilter;

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

@ -116,7 +116,8 @@ class SourcesTree extends _react.Component {
debuggeeUrl,
projectRoot,
uncollapsedTree,
sourceTree
sourceTree,
focusedItem: this.state.focusedItem
}));
}
}

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

@ -10,6 +10,7 @@ DIRS += [
DevToolsModules(
'index.js',
'Outline.js',
'OutlineFilter.js',
'SourcesTree.js',
'SourcesTreeItem.js',
)

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

@ -1,24 +1,35 @@
"use strict";
var _react = require("devtools/client/shared/vendor/react");
var _react2 = _interopRequireDefault(_react);
var _reactDom = require("devtools/client/shared/vendor/react-dom");
var _reactDom2 = _interopRequireDefault(_reactDom);
var _devtoolsEnvironment = require("devtools/client/debugger/new/dist/vendors").vendored["devtools-environment"];
var _client = require("./client/index");
var _bootstrap = require("./utils/bootstrap");
var _sourceQueue = require("./utils/source-queue");
var _sourceQueue2 = _interopRequireDefault(_sourceQueue);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* 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/>. */
// @flow
import React from "react";
import ReactDOM from "react-dom";
import { isFirefoxPanel } from "devtools-environment";
import { onConnect } from "./client";
import { teardownWorkers } from "./utils/bootstrap";
import sourceQueue from "./utils/source-queue";
function unmountRoot() {
const mount = document.querySelector("#mount .launchpad-root");
ReactDOM.unmountComponentAtNode(mount);
_reactDom2.default.unmountComponentAtNode(mount);
}
if (isFirefoxPanel()) {
if ((0, _devtoolsEnvironment.isFirefoxPanel)()) {
module.exports = {
bootstrap: ({
threadClient,
@ -26,38 +37,45 @@ if (isFirefoxPanel()) {
debuggerClient,
sourceMaps,
toolboxActions
}: any) => {
return onConnect(
{
tab: { clientType: "firefox" },
}) => {
return (0, _client.onConnect)({
tab: {
clientType: "firefox"
},
tabConnection: {
tabTarget,
threadClient,
debuggerClient
}
}, {
services: {
sourceMaps
},
{
services: { sourceMaps },
toolboxActions
}
);
});
},
destroy: () => {
unmountRoot();
sourceQueue.clear();
teardownWorkers();
_sourceQueue2.default.clear();
(0, _bootstrap.teardownWorkers)();
}
};
} else {
const { bootstrap, L10N } = require("devtools-launchpad");
const {
bootstrap,
L10N
} = require("devtools/shared/flags");
window.L10N = L10N;
// $FlowIgnore:
window.L10N.setBundle(require("../assets/panel/debugger.properties"));
window.L10N = L10N; // $FlowIgnore:
bootstrap(React, ReactDOM).then(connection => {
onConnect(connection, {
services: { sourceMaps: require("devtools-source-map") },
window.L10N.setBundle(require("devtools/shared/flags"));
bootstrap(_react2.default, _reactDom2.default).then(connection => {
(0, _client.onConnect)(connection, {
services: {
sourceMaps: require("devtools/client/shared/source-map/index.js")
},
toolboxActions: {}
});
});

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

@ -98,7 +98,11 @@ function update(state = initialSourcesState(), action) {
location = { ...action.location,
url: action.source.url
};
if (action.source.url) {
_prefs.prefs.pendingSelectedLocation = location;
}
return { ...state,
selectedLocation: {
sourceId: action.source.id,

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

@ -70,24 +70,37 @@ function removeSourcesFromTabList(tabs, sources) {
function updateTabList(tabs, {
url,
framework = null,
sourceId,
isOriginal = false
}) {
const currentIndex = tabs.findIndex(tab => isSimilarTab(tab, url, isOriginal));
// Set currentIndex to -1 for URL-less tabs so that they aren't
// filtered by isSimilarTab
const currentIndex = url ? tabs.findIndex(tab => isSimilarTab(tab, url, isOriginal)) : -1;
if (currentIndex === -1) {
tabs = [{
url,
framework,
sourceId,
isOriginal
}, ...tabs];
} else if (framework) {
tabs[currentIndex].framework = framework;
}
_prefs.asyncStore.tabs = tabs;
_prefs.asyncStore.tabs = persistTabs(tabs);
return tabs;
}
function persistTabs(tabs) {
return tabs.filter(tab => tab.url).map(tab => {
const newTab = { ...tab
};
delete newTab.sourceId;
return newTab;
});
}
function moveTabInList(tabs, {
url,
tabIndex: newIndex
@ -166,8 +179,15 @@ function getNewSelectedSourceId(state, availableTabs) {
const getTabs = exports.getTabs = state => state.tabs;
const getSourceTabs = exports.getSourceTabs = (0, _reselect.createSelector)(getTabs, _sources.getSources, _sources.getUrls, (tabs, sources, urls) => tabs.filter(tab => (0, _sources.getSpecificSourceByUrlInSources)(sources, urls, tab.url, tab.isOriginal)));
const getSourcesForTabs = exports.getSourcesForTabs = (0, _reselect.createSelector)(getSourceTabs, _sources.getSources, _sources.getUrls, (tabs, sources, urls) => {
return tabs.map(tab => (0, _sources.getSpecificSourceByUrlInSources)(sources, urls, tab.url, tab.isOriginal)).filter(Boolean);
});
const getSourceTabs = exports.getSourceTabs = (0, _reselect.createSelector)(getTabs, _sources.getSources, _sources.getUrls, (tabs, sources, urls) => tabs.filter(tab => getTabWithOrWithoutUrl(tab, sources, urls)));
const getSourcesForTabs = exports.getSourcesForTabs = (0, _reselect.createSelector)(getSourceTabs, _sources.getSources, _sources.getUrls, (tabs, sources, urls) => tabs.map(tab => getTabWithOrWithoutUrl(tab, sources, urls)).filter(Boolean));
function getTabWithOrWithoutUrl(tab, sources, urls) {
if (tab.url) {
return (0, _sources.getSpecificSourceByUrlInSources)(sources, urls, tab.url, tab.isOriginal);
}
return tab.sourceId ? sources[tab.sourceId] : null;
}
exports.default = update;

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

@ -21,7 +21,7 @@ const libraryMap = [{
pattern: /preact/i
}, {
label: "React",
pattern: /react/i
pattern: /(node_modules\/react)|(react(\.[a-z]+)*\.js$)/i
}, {
label: "Immutable",
pattern: /immutable/i

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

@ -170,7 +170,7 @@ function getFilename(source) {
id
} = source;
if (!url) {
if (!getRawSourceURL(url)) {
return getFormattedSourceId(id);
}

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

@ -24,13 +24,32 @@ function newSourcesSet(newSources, prevSources) {
return uniqSources;
}
function findFocusedItemInTree(newSourceTree, focusedItem, debuggeeHost) {
const parts = focusedItem.path.split("/").filter(p => p !== "");
let path = "";
return parts.reduce((subTree, part, index) => {
if (subTree === undefined || subTree === null) {
return null;
} else if ((0, _utils.isSource)(subTree)) {
return subTree;
}
path = path ? `${path}/${part}` : part;
const {
index: childIndex
} = (0, _treeOrder.findNodeInContents)(subTree, (0, _treeOrder.createTreeNodeMatcher)(part, !(0, _utils.partIsFile)(index, parts, focusedItem), debuggeeHost));
return subTree.contents[childIndex];
}, newSourceTree);
}
function updateTree({
newSources,
prevSources,
debuggeeUrl,
projectRoot,
uncollapsedTree,
sourceTree
sourceTree,
focusedItem
}) {
const newSet = newSourcesSet(newSources, prevSources);
const debuggeeHost = (0, _treeOrder.getDomain)(debuggeeUrl);
@ -40,10 +59,15 @@ function updateTree({
}
const newSourceTree = (0, _collapseTree.collapseTree)(uncollapsedTree);
if (focusedItem) {
focusedItem = findFocusedItemInTree(newSourceTree, focusedItem, debuggeeHost);
}
return {
uncollapsedTree,
sourceTree: newSourceTree,
parentMap: (0, _utils.createParentMap)(newSourceTree),
focusedItem: null
focusedItem
};
}

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

@ -1,9 +1,6 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
// Tests that the editor highlights the correct location when the
// debugger pauses
function getItems(dbg) {
return findAllElements(dbg, "outlineItems");
}
@ -12,6 +9,8 @@ function getNthItem(dbg, index) {
return findElement(dbg, "outlineItem", index);
}
// Tests that the editor highlights the correct location when the
// debugger pauses
add_task(async function() {
const dbg = await initDebugger("doc-scripts.html");
const {
@ -59,3 +58,71 @@ add_task(async function() {
"Alphabetized first function is correct"
);
});
// Tests the outline pane fuzzy filtering of outline items
add_task(async function() {
const dbg = await initDebugger("doc-scripts.html");
await selectSource(dbg, "long", 1);
findElementWithSelector(dbg, ".outline-tab").click();
// turn off alphetical sort if active
const alphabetizeButton = findElementWithSelector(
dbg,
".outline-footer button"
);
if (alphabetizeButton.className === "active") {
alphabetizeButton.click();
}
const outlineFilter = findElementWithSelector(dbg, ".outline-filter-input");
ok(outlineFilter, "Outline filter is present");
outlineFilter.blur();
ok(
!findElementWithSelector(dbg, ".outline-filter-input.focused"),
"does not have class focused when not focused"
);
outlineFilter.focus();
ok(
findElementWithSelector(dbg, ".outline-filter-input.focused"),
"has class focused when focused"
);
is(getItems(dbg).length, 9, "9 items in the unfiltered list");
// filter all items starting with t
type(dbg, "t");
is(getItems(dbg).length, 4, "4 items in the list after 't' filter");
ok(getItems(dbg)[0].textContent.includes("TodoModel(key)"), "item TodoModel");
ok(
getItems(dbg)[1].textContent.includes("toggleAll(checked)"),
"item toggleAll"
);
ok(
getItems(dbg)[2].textContent.includes("toggle(todoToToggle)"),
"item toggle"
);
ok(getItems(dbg)[3].textContent.includes("testModel()"), "item testModel");
// filter using term 'tog'
type(dbg, "og");
is(getItems(dbg).length, 2, "2 items in the list after 'tog' filter");
ok(
getItems(dbg)[0].textContent.includes("toggleAll(checked)"),
"item toggleAll"
);
ok(
getItems(dbg)[1].textContent.includes("toggle(todoToToggle)"),
"item toggle"
);
pressKey(dbg, "Escape");
is(getItems(dbg).length, 9, "9 items in the list after escape pressed");
// check that the term 'todo' includes items with todo
type(dbg, "todo");
is(getItems(dbg).length, 2, "2 items in the list after 'todo' filter");
ok(getItems(dbg)[0].textContent.includes("TodoModel(key)"), "item TodoModel");
ok(getItems(dbg)[1].textContent.includes("addTodo(title)"), "item addTodo");
});

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

@ -2,25 +2,6 @@
* http://creativecommons.org/publicdomain/zero/1.0/ */
// Test keyboard arrow behaviour
async function waitForNodeToGainFocus(dbg, index) {
await waitUntil(() => {
const element = findElement(dbg, "sourceNode", index);
if (element) {
return element.classList.contains("focused");
}
return false;
}, `waiting for source node ${index} to be focused`);
}
async function assertNodeIsFocused(dbg, index) {
await waitForNodeToGainFocus(dbg, index);
const node = findElement(dbg, "sourceNode", index);
ok(node.classList.contains("focused"), `node ${index} is focused`);
}
add_task(async function() {
const dbg = await initDebugger("doc-sources.html");
await waitForSources(dbg, "simple1", "simple2", "nested-source", "long.js");

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

@ -40,7 +40,7 @@ add_task(async function() {
ok(fourthNode.classList.contains("focused"), "4th node is focused");
ok(selectedSource.includes("nested-source.js"), "nested-source is selected");
await assertNodeIsFocused(dbg, 4);
await waitForSelectedSource(dbg, "nested-source");
// Make sure new sources appear in the list.
@ -51,6 +51,7 @@ add_task(async function() {
});
await waitForSourceCount(dbg, 9);
await assertNodeIsFocused(dbg, 4);
is(
getLabel(dbg, 7),
"math.min.js",

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

@ -37,3 +37,28 @@ add_task(async function() {
await reload(dbg, "simple1", "simple2");
is(countTabs(dbg), 0);
});
// Test that URL-less sources have tabs added to the UI but
// do not persist upon reload
add_task(async function() {
const dbg = await initDebugger("doc-scripts.html", "simple1", "simple2");
await selectSource(dbg, "simple1");
await selectSource(dbg, "simple2");
is(countTabs(dbg), 2);
invokeInTab("doEval");
await waitForPaused(dbg);
await resume(dbg);
is(countTabs(dbg), 3);
invokeInTab("doEval");
await waitForPaused(dbg);
await resume(dbg);
is(countTabs(dbg), 4);
// Test reloading the debugger
await reload(dbg, "simple1", "simple2");
is(countTabs(dbg), 2);
});

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

@ -1340,3 +1340,21 @@ async function assertSourceCount(dbg, count) {
await waitForSourceCount(dbg, count);
is(findAllElements(dbg, "sourceNodes").length, count, `${count} sources`);
}
async function waitForNodeToGainFocus(dbg, index) {
await waitUntil(() => {
const element = findElement(dbg, "sourceNode", index);
if (element) {
return element.classList.contains("focused");
}
return false;
}, `waiting for source node ${index} to be focused`);
}
async function assertNodeIsFocused(dbg, index) {
await waitForNodeToGainFocus(dbg, index);
const node = findElement(dbg, "sourceNode", index);
ok(node.classList.contains("focused"), `node ${index} is focused`);
}

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

@ -606,6 +606,10 @@ sources.header=Sources
# LOCALIZATION NOTE (outline.header): Outline left sidebar header
outline.header=Outline
# LOCALIZATION NOTE (outline.placeholder): Placeholder text for the filter input
# element
outline.placeholder=Filter functions
# LOCALIZATION NOTE (outline.sortLabel): Label for the sort button
outline.sortLabel=Sort by name