diff --git a/devtools/client/debugger/new/README.mozilla b/devtools/client/debugger/new/README.mozilla
index 58264a34a097..d1101d7e2c31 100644
--- a/devtools/client/debugger/new/README.mozilla
+++ b/devtools/client/debugger/new/README.mozilla
@@ -1,9 +1,9 @@
This is the debugger.html project output.
See https://github.com/devtools-html/debugger.html
-Version 104
+Version 105
-Comparison: https://github.com/devtools-html/debugger.html/compare/release-103...release-104
+Comparison: https://github.com/devtools-html/debugger.html/compare/release-104...release-105
Packages:
- babel-plugin-transform-es2015-modules-commonjs @6.26.2
diff --git a/devtools/client/debugger/new/dist/debugger.css b/devtools/client/debugger/new/dist/debugger.css
index 7aa5af9b1cbc..91b951ed3eec 100644
--- a/devtools/client/debugger/new/dist/debugger.css
+++ b/devtools/client/debugger/new/dist/debugger.css
@@ -276,6 +276,22 @@ button.jump-definition {
background-color: var(--theme-highlight-blue);
}
+/******************************************************************************/
+/* Invoke getter button */
+
+button.invoke-getter {
+ mask: url("resource://devtools/client/shared/components/reps/images/input.svg") no-repeat;
+ display: inline-block;
+ background-color: var(--comment-node-color);
+ height: 12px;
+ vertical-align:bottom;
+ border:none;
+}
+
+.invoke-getter:hover {
+ background-color: var(--theme-highlight-blue);
+}
+
/******************************************************************************/
/* "more…" ellipsis */
.more-ellipsis {
@@ -337,24 +353,29 @@ button.jump-definition {
cursor: default;
}
-.tree-node img.arrow {
- mask: url("resource://devtools/client/debugger/new/images/arrow.svg") no-repeat;
- mask-size: 100%;
+.tree-node button.arrow {
+ background:url("resource://devtools/client/debugger/new/images/arrow.svg") no-repeat;
+ background-size:contain;
+ background-position:center center;
width: 9px;
height: 9px;
+ border:0;
+ padding:0;
margin-inline-start: 1px;
margin-inline-end: 4px;
- background-color: var(--theme-splitter-color, #9B9B9B);
transform: rotate(-90deg);
+ transform-origin: center center;
transition: transform 0.125s ease;
align-self: center;
+ -moz-context-properties: fill;
+ fill: var(--theme-splitter-color, #9B9B9B);
}
-html[dir="rtl"] .tree-node img.arrow {
+html[dir="rtl"] .tree-node button.arrow {
transform: rotate(90deg);
}
-.tree-node img.arrow.expanded.expanded {
+.tree-node button.arrow.expanded.expanded {
transform: rotate(0deg);
}
@@ -363,8 +384,8 @@ html[dir="rtl"] .tree-node img.arrow {
background-color: var(--theme-selection-background, #0a84ff);
}
-.tree-node.focused img.arrow {
- background-color: currentColor;
+.tree-node.focused button.arrow {
+ fill: currentColor;
}
/* 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
@@ -404,7 +425,7 @@ html[dir="rtl"] .tree-node img.arrow {
color: var(--theme-comment);
}
-.object-inspector .tree-node img.arrow {
+.object-inspector .tree-node .arrow {
display: inline-block;
vertical-align: middle;
}
@@ -2665,7 +2686,7 @@ menuseparator {
.call-site {
position: relative;
- border-bottom: 2px solid lightgrey;
+ display: inline;
cursor: pointer;
}
@@ -2680,20 +2701,8 @@ menuseparator {
height: 12px;
}
-.call-site-bp {
- position: relative;
- border-bottom: 2px solid #aed3ef;
- cursor: pointer;
-}
-
-.call-site-bp::before {
- content: "";
- mask: url("resource://devtools/client/debugger/new/images/column-marker.svg") no-repeat 100% 100%;
- mask-size: contain;
- display: inline-block;
- background-color: var(--blue-55);
- width: 9px;
- height: 12px;
+.call-site.active::before {
+ opacity: 1;
}
.theme-dark .call-site {
@@ -2950,7 +2959,8 @@ html[dir="rtl"] .editor-mount {
color: var(--theme-comment);
}
-.debug-expression {
+.debug-expression,
+.new-debug-line .call-site {
background-color: var(--debug-expression-background);
}
@@ -3612,7 +3622,7 @@ html[dir="rtl"] .breakpoints-list .breakpoint .breakpoint-line {
margin-inline-start: 4px;
}
-:root.theme-dark .annotation-logo svg path {
+:root.theme-dark .annotation-logo:not(.angular) svg path {
fill: var(--theme-highlight-blue);
}
/* This Source Code Form is subject to the terms of the Mozilla Public
diff --git a/devtools/client/debugger/new/dist/parser-worker.js b/devtools/client/debugger/new/dist/parser-worker.js
index 8c88edba5ebe..4def7a2f61e7 100644
--- a/devtools/client/debugger/new/dist/parser-worker.js
+++ b/devtools/client/debugger/new/dist/parser-worker.js
@@ -1015,6 +1015,7 @@ exports.isVariable = isVariable;
exports.isComputedExpression = isComputedExpression;
exports.getMemberExpression = getMemberExpression;
exports.getVariables = getVariables;
+exports.getPatternIdentifiers = getPatternIdentifiers;
exports.isTopLevel = isTopLevel;
var _types = __webpack_require__(2268);
@@ -1164,14 +1165,15 @@ function getVariables(dec) {
return [];
}
- // NOTE: it's possible that an element is empty
+ // NOTE: it's possible that an element is empty or has several variables
// e.g. const [, a] = arr
+ // e.g. const [{a, b }] = 2
return dec.id.elements.filter(element => element).map(element => {
return {
- name: t.isAssignmentPattern(element) ? element.left.name : element.name || element.argument.name,
+ name: t.isAssignmentPattern(element) ? element.left.name : element.name || element.argument && element.argument.name,
location: element.loc
};
- });
+ }).filter(({ name }) => name);
}
return [{
@@ -1180,6 +1182,36 @@ function getVariables(dec) {
}];
}
+function getPatternIdentifiers(pattern) {
+ let items = [];
+ if (t.isObjectPattern(pattern)) {
+ items = pattern.properties.map(({ value }) => value);
+ }
+
+ if (t.isArrayPattern(pattern)) {
+ items = pattern.elements;
+ }
+
+ return getIdentifiers(items);
+}
+
+function getIdentifiers(items) {
+ let ids = [];
+ items.forEach(function (item) {
+ if (t.isObjectPattern(item) || t.isArrayPattern(item)) {
+ ids = ids.concat(getPatternIdentifiers(item));
+ } else if (t.isIdentifier(item)) {
+ const { start, end } = item.loc;
+ ids.push({
+ name: item.name,
+ expression: item.name,
+ location: { start, end }
+ });
+ }
+ });
+ return ids;
+}
+
// Top Level checks the number of "body" nodes in the ancestor chain
// if the node is top-level, then it shoul only have one body.
function isTopLevel(ancestors) {
@@ -1450,7 +1482,7 @@ function extractSymbol(path, symbols) {
});
}
- if (t.isIdentifier(path) && !t.isGenericTypeAnnotation(path.parent)) {
+ if (t.isIdentifier(path) && !t.isGenericTypeAnnotation(path.parent) && !t.isObjectProperty(path.parent) && !t.isArrayPattern(path.parent)) {
let { start, end } = path.node.loc;
// We want to include function params, but exclude the function name
@@ -1490,25 +1522,11 @@ function extractSymbol(path, symbols) {
if (t.isVariableDeclarator(path)) {
const nodeId = path.node.id;
- if (t.isArrayPattern(nodeId)) {
- return;
- }
-
- const properties = nodeId.properties && t.objectPattern(nodeId.properties) ? nodeId.properties : [{
- value: { name: nodeId.name },
- loc: path.node.loc
- }];
-
- properties.forEach(function (property) {
- const { start, end } = property.loc;
- symbols.identifiers.push({
- name: property.value.name,
- expression: property.value.name,
- location: { start, end }
- });
- });
+ const ids = (0, _helpers.getPatternIdentifiers)(nodeId);
+ symbols.identifiers = [...symbols.identifiers, ...ids];
}
}
+
/* eslint-enable complexity */
function extractSymbols(sourceId) {
diff --git a/devtools/client/debugger/new/dist/vendors.css b/devtools/client/debugger/new/dist/vendors.css
index 404c74ce1e9c..e9e5a9f16879 100644
--- a/devtools/client/debugger/new/dist/vendors.css
+++ b/devtools/client/debugger/new/dist/vendors.css
@@ -54,24 +54,29 @@
cursor: default;
}
-.tree-node img.arrow {
- mask: url("resource://devtools/client/debugger/new/images/arrow.svg") no-repeat;
- mask-size: 100%;
+.tree-node button.arrow {
+ background:url("resource://devtools/client/debugger/new/images/arrow.svg") no-repeat;
+ background-size:contain;
+ background-position:center center;
width: 9px;
height: 9px;
+ border:0;
+ padding:0;
margin-inline-start: 1px;
margin-inline-end: 4px;
- background-color: var(--theme-splitter-color, #9B9B9B);
transform: rotate(-90deg);
+ transform-origin: center center;
transition: transform 0.125s ease;
align-self: center;
+ -moz-context-properties: fill;
+ fill: var(--theme-splitter-color, #9B9B9B);
}
-html[dir="rtl"] .tree-node img.arrow {
+html[dir="rtl"] .tree-node button.arrow {
transform: rotate(90deg);
}
-.tree-node img.arrow.expanded.expanded {
+.tree-node button.arrow.expanded.expanded {
transform: rotate(0deg);
}
@@ -80,8 +85,8 @@ html[dir="rtl"] .tree-node img.arrow {
background-color: var(--theme-selection-background, #0a84ff);
}
-.tree-node.focused img.arrow {
- background-color: currentColor;
+.tree-node.focused button.arrow {
+ fill: currentColor;
}
/* vim:set ts=2 sw=2 sts=2 et: */
/* This Source Code Form is subject to the terms of the Mozilla Public
diff --git a/devtools/client/debugger/new/dist/vendors.js b/devtools/client/debugger/new/dist/vendors.js
index 4cf389e3bc05..97ef104453bd 100644
--- a/devtools/client/debugger/new/dist/vendors.js
+++ b/devtools/client/debugger/new/dist/vendors.js
@@ -4622,7 +4622,7 @@ module.exports = ""
+module.exports = ""
/***/ }),
@@ -4678,7 +4678,7 @@ module.exports = ""
+module.exports = ""
/***/ }),
@@ -6012,7 +6012,7 @@ class ArrowExpander extends Component {
if (expanded) {
classNames.push("expanded");
}
- return _reactDomFactories2.default.img({
+ return _reactDomFactories2.default.button({
className: classNames.join(" ")
});
}
diff --git a/devtools/client/debugger/new/images/moz.build b/devtools/client/debugger/new/images/moz.build
index fa9791a08037..551d68c287bd 100644
--- a/devtools/client/debugger/new/images/moz.build
+++ b/devtools/client/debugger/new/images/moz.build
@@ -21,7 +21,6 @@ DevToolsModules(
'folder.svg',
'help.svg',
'javascript.svg',
- 'next.svg',
'pause.svg',
'prettyPrint.svg',
'react.svg',
diff --git a/devtools/client/debugger/new/images/next.svg b/devtools/client/debugger/new/images/next.svg
deleted file mode 100644
index fb66d5b3f7ff..000000000000
--- a/devtools/client/debugger/new/images/next.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
\ No newline at end of file
diff --git a/devtools/client/debugger/new/src/actions/ui.js b/devtools/client/debugger/new/src/actions/ui.js
index c73208c7701a..ac225452fb61 100644
--- a/devtools/client/debugger/new/src/actions/ui.js
+++ b/devtools/client/debugger/new/src/actions/ui.js
@@ -14,7 +14,7 @@ import {
} from "../selectors";
import { selectSource } from "../actions/sources/select";
import type { ThunkArgs, panelPositionType } from "./types";
-import { getEditor } from "../utils/editor";
+import { getEditor, getLocationsInViewport } from "../utils/editor";
import { searchContents } from "./file-search";
import type {
@@ -201,6 +201,13 @@ export function setProjectDirectoryRoot(newRoot: string) {
};
}
+export function updateViewport() {
+ return {
+ type: "SET_VIEWPORT",
+ viewport: getLocationsInViewport(getEditor())
+ };
+}
+
export function setOrientation(orientation: OrientationType) {
return { type: "SET_ORIENTATION", orientation };
}
diff --git a/devtools/client/debugger/new/src/components/Editor/ColumnBreakpoint.js b/devtools/client/debugger/new/src/components/Editor/ColumnBreakpoint.js
new file mode 100644
index 000000000000..e55aa7912fe6
--- /dev/null
+++ b/devtools/client/debugger/new/src/components/Editor/ColumnBreakpoint.js
@@ -0,0 +1,80 @@
+/* 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 . */
+
+// @flow
+import { PureComponent } from "react";
+import classnames from "classnames";
+import { getDocument } from "../../utils/editor";
+
+// eslint-disable-next-line max-len
+import type { ColumnBreakpoint as ColumnBreakpointType } from "../../selectors/visibleColumnBreakpoints";
+
+type Bookmark = {
+ clear: Function
+};
+
+type Props = {
+ callSite: Object,
+ editor: Object,
+ source: Object,
+ enabled: boolean,
+ toggleBreakpoint: (number, number) => void,
+ columnBreakpoint: ColumnBreakpointType
+};
+
+const breakpointImg = document.createElement("div");
+function makeBookmark(isActive, { onClick }) {
+ const bp = breakpointImg.cloneNode(true);
+ bp.className = classnames("call-site", {
+ active: isActive
+ });
+ bp.onclick = onClick;
+ return bp;
+}
+
+export default class CallSite extends PureComponent {
+ addCallSite: Function;
+ bookmark: ?Bookmark;
+
+ addCallSite = (nextProps: ?Props) => {
+ const { columnBreakpoint, source } = nextProps || this.props;
+ const sourceId = source.id;
+ const { line, column } = columnBreakpoint.location;
+ const widget = makeBookmark(columnBreakpoint.enabled, {
+ onClick: this.toggleBreakpoint
+ });
+ const doc = getDocument(sourceId);
+ this.bookmark = doc.setBookmark({ line: line - 1, ch: column }, { widget });
+ };
+
+ clearCallSite = () => {
+ if (this.bookmark) {
+ this.bookmark.clear();
+ this.bookmark = null;
+ }
+ };
+
+ toggleBreakpoint = () => {
+ const { columnBreakpoint, toggleBreakpoint } = this.props;
+ const { line, column } = columnBreakpoint.location;
+ toggleBreakpoint(line, column);
+ };
+
+ componentDidMount() {
+ this.addCallSite();
+ }
+
+ componentWillUnmount() {
+ this.clearCallSite();
+ }
+
+ componentDidUpdate() {
+ this.clearCallSite();
+ this.addCallSite();
+ }
+
+ render() {
+ return null;
+ }
+}
diff --git a/devtools/client/debugger/new/src/components/Editor/ColumnBreakpoints.js b/devtools/client/debugger/new/src/components/Editor/ColumnBreakpoints.js
new file mode 100644
index 000000000000..75603744da24
--- /dev/null
+++ b/devtools/client/debugger/new/src/components/Editor/ColumnBreakpoints.js
@@ -0,0 +1,67 @@
+/* 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 . */
+
+import React, { Component } from "react";
+import { connect } from "react-redux";
+
+import ColumnBreakpoint from "./ColumnBreakpoint";
+import "./ColumnBreakpoints.css";
+
+import { getSelectedSource, visibleColumnBreakpoints } from "../../selectors";
+import { makeLocationId } from "../../utils/breakpoint";
+import actions from "../../actions";
+
+import type { Source } from "../../types";
+// eslint-disable-next-line max-len
+import type { ColumnBreakpoint as ColumnBreakpointType } from "../../selectors/visibleColumnBreakpoints";
+
+class ColumnBreakpoints extends Component {
+ props: {
+ editor: Object,
+ selectedSource: Source,
+ columnBreakpoints: ColumnBreakpointType[]
+ };
+
+ render() {
+ const {
+ editor,
+ columnBreakpoints,
+ selectedSource,
+ toggleBreakpoint
+ } = this.props;
+
+ if (!selectedSource || selectedSource.isBlackBoxed) {
+ return null;
+ }
+
+ let breakpoints;
+ editor.codeMirror.operation(() => {
+ breakpoints = columnBreakpoints.map(breakpoint => (
+
+ ));
+ });
+ return {breakpoints}
;
+ }
+}
+
+const mapStateToProps = state => {
+ return {
+ selectedSource: getSelectedSource(state),
+ columnBreakpoints: visibleColumnBreakpoints(state)
+ };
+};
+
+const { toggleBreakpoint } = actions;
+const mapDispatchToProps = { toggleBreakpoint };
+
+export default connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(ColumnBreakpoints);
diff --git a/devtools/client/debugger/new/src/components/Editor/Tabs.js b/devtools/client/debugger/new/src/components/Editor/Tabs.js
index 2537b71c141a..cfbacf56c5ef 100644
--- a/devtools/client/debugger/new/src/components/Editor/Tabs.js
+++ b/devtools/client/debugger/new/src/components/Editor/Tabs.js
@@ -76,12 +76,16 @@ class Tabs extends PureComponent {
componentDidMount() {
window.requestIdleCallback(this.updateHiddenTabs);
window.addEventListener("resize", this.onResize);
- window.document.querySelector(".editor-pane").addEventListener("resizeend", this.onResize);
+ window.document
+ .querySelector(".editor-pane")
+ .addEventListener("resizeend", this.onResize);
}
componentWillUnmount() {
window.removeEventListener("resize", this.onResize);
- window.document.querySelector(".editor-pane").removeEventListener("resizeend", this.onResize);
+ window.document
+ .querySelector(".editor-pane")
+ .removeEventListener("resizeend", this.onResize);
}
/*
diff --git a/devtools/client/debugger/new/src/components/Editor/index.js b/devtools/client/debugger/new/src/components/Editor/index.js
index d7cc4e296098..45be88063eb5 100644
--- a/devtools/client/debugger/new/src/components/Editor/index.js
+++ b/devtools/client/debugger/new/src/components/Editor/index.js
@@ -9,6 +9,8 @@ import React, { PureComponent } from "react";
import ReactDOM from "react-dom";
import { connect } from "react-redux";
import classnames from "classnames";
+import { debounce } from "lodash";
+
import { isLoaded } from "../../utils/source";
import { isFirefox } from "devtools-environment";
import { features } from "../../utils/prefs";
@@ -30,7 +32,7 @@ import SearchBar from "./SearchBar";
import HighlightLines from "./HighlightLines";
import Preview from "./Preview";
import Breakpoints from "./Breakpoints";
-import CallSites from "./CallSites";
+import ColumnBreakpoints from "./ColumnBreakpoints";
import DebugLine from "./DebugLine";
import HighlightLine from "./HighlightLine";
import EmptyLines from "./EmptyLines";
@@ -91,7 +93,8 @@ export type Props = {
toggleBreakpointsAtLine: (?number) => void,
addOrToggleDisabledBreakpoint: (?number) => void,
jumpToMappedLocation: any => void,
- traverseResults: (boolean, Object) => void
+ traverseResults: (boolean, Object) => void,
+ updateViewport: void => void
};
type State = {
@@ -157,6 +160,7 @@ class Editor extends PureComponent {
codeMirrorWrapper.addEventListener("keydown", e => this.onKeyDown(e));
codeMirrorWrapper.addEventListener("click", e => this.onClick(e));
codeMirrorWrapper.addEventListener("mouseover", onMouseOver(codeMirror));
+ codeMirror.on("scroll", this.onEditorScroll);
const toggleFoldMarkerVisibility = e => {
if (node instanceof HTMLElement) {
@@ -277,6 +281,8 @@ class Editor extends PureComponent {
this.toggleConditionalPanel(line);
};
+ onEditorScroll = debounce(this.props.updateViewport, 200);
+
onKeyDown(e: KeyboardEvent) {
const { codeMirror } = this.state.editor;
const { key, target } = e;
@@ -548,7 +554,9 @@ class Editor extends PureComponent {
- {features.columnBreakpoints ? : null}
+ {features.columnBreakpoints ? (
+
+ ) : null}
);
}
@@ -607,6 +615,7 @@ export default connect(
toggleBreakpointsAtLine: actions.toggleBreakpointsAtLine,
addOrToggleDisabledBreakpoint: actions.addOrToggleDisabledBreakpoint,
jumpToMappedLocation: actions.jumpToMappedLocation,
- traverseResults: actions.traverseResults
+ traverseResults: actions.traverseResults,
+ updateViewport: actions.updateViewport
}
)(Editor);
diff --git a/devtools/client/debugger/new/src/components/Editor/moz.build b/devtools/client/debugger/new/src/components/Editor/moz.build
index 19d406fa2e17..f8107c90fa91 100644
--- a/devtools/client/debugger/new/src/components/Editor/moz.build
+++ b/devtools/client/debugger/new/src/components/Editor/moz.build
@@ -10,8 +10,8 @@ DIRS += [
DebuggerModules(
'Breakpoint.js',
'Breakpoints.js',
- 'CallSite.js',
- 'CallSites.js',
+ 'ColumnBreakpoint.js',
+ 'ColumnBreakpoints.js',
'ConditionalPanel.js',
'DebugLine.js',
'EditorMenu.js',
diff --git a/devtools/client/debugger/new/src/components/SecondaryPanes/Breakpoints/index.js b/devtools/client/debugger/new/src/components/SecondaryPanes/Breakpoints/index.js
index 39fc811e3144..b4b6d9b92e2e 100644
--- a/devtools/client/debugger/new/src/components/SecondaryPanes/Breakpoints/index.js
+++ b/devtools/client/debugger/new/src/components/SecondaryPanes/Breakpoints/index.js
@@ -15,7 +15,7 @@ import BreakpointHeading from "./BreakpointHeading";
import actions from "../../../actions";
import { getDisplayPath } from "../../../utils/source";
-import { makeLocationId } from "../../../utils/breakpoint";
+import { makeLocationId, sortBreakpoints } from "../../../utils/breakpoint";
import { getSelectedSource, getBreakpointSources } from "../../../selectors";
@@ -79,6 +79,8 @@ class Breakpoints extends Component {
return [
...breakpointSources.map(({ source, breakpoints, i }) => {
const path = getDisplayPath(source, sources);
+ const sortedBreakpoints = sortBreakpoints(breakpoints);
+
return [
{
path={path}
key={source.url}
/>,
- ...breakpoints.map(breakpoint => (
+ ...sortedBreakpoints.map(breakpoint => (
. */
+
+import { groupBy, hasIn } from "lodash";
+import { createSelector } from "reselect";
+
+import { getViewport } from "../selectors";
+import { getVisibleBreakpoints } from "./visibleBreakpoints";
+import { getVisiblePausePoints } from "./visiblePausePoints";
+
+import type { Location } from "../types";
+
+export type ColumnBreakpoint = {|
+ +location: Location,
+ +enabled: boolean
+|};
+
+function contains(location, range) {
+ return (
+ location.line >= range.start.line &&
+ location.line <= range.end.line &&
+ location.column >= range.start.column &&
+ location.column <= range.end.column
+ );
+}
+
+function groupBreakpoints(breakpoints) {
+ const map = groupBy(breakpoints, ({ location }) => location.line);
+ for (const line in map) {
+ map[line] = groupBy(map[line], ({ location }) => location.column);
+ }
+
+ return map;
+}
+
+function isEnabled(location, breakpointMap) {
+ const { line, column } = location;
+ return hasIn(breakpointMap, [line, column]);
+}
+
+export function formatColumnBreakpoints(columnBreakpoints) {
+ console.log(
+ "Column Breakpoints\n\n",
+ columnBreakpoints
+ .map(
+ ({ location, enabled }) =>
+ `(${location.line}, ${location.column}) ${enabled}`
+ )
+ .join("\n")
+ );
+}
+
+export function getColumnBreakpoints(pausePoints, breakpoints, viewport) {
+ if (!pausePoints) {
+ return [];
+ }
+
+ const breakpointMap = groupBreakpoints(breakpoints);
+ const columnBreakpoints = pausePoints
+ .filter(({ types }) => types.break)
+ .filter(({ location }) => breakpointMap[location.line])
+ .filter(({ location }) => viewport && contains(location, viewport));
+
+ return columnBreakpoints.map(({ location }) => ({
+ location,
+ enabled: isEnabled(location, breakpointMap)
+ }));
+}
+
+export const visibleColumnBreakpoints = createSelector(
+ getVisiblePausePoints,
+ getVisibleBreakpoints,
+ getViewport,
+ getColumnBreakpoints
+);
diff --git a/devtools/client/debugger/new/src/selectors/visiblePausePoints.js b/devtools/client/debugger/new/src/selectors/visiblePausePoints.js
new file mode 100644
index 000000000000..7d332c85da88
--- /dev/null
+++ b/devtools/client/debugger/new/src/selectors/visiblePausePoints.js
@@ -0,0 +1,17 @@
+/* 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 . */
+
+import { getSelectedSource } from "../reducers/sources";
+import { getPausePoints } from "../reducers/ast";
+import { convertToList } from "../utils/pause/pausePoints";
+
+export function getVisiblePausePoints(state) {
+ const source = getSelectedSource(state);
+ if (!source) {
+ return null;
+ }
+
+ const pausePoints = getPausePoints(state, source.id);
+ return convertToList(pausePoints);
+}
diff --git a/devtools/client/debugger/new/src/utils/breakpoint/index.js b/devtools/client/debugger/new/src/utils/breakpoint/index.js
index bbed30c1b545..79b234e41509 100644
--- a/devtools/client/debugger/new/src/utils/breakpoint/index.js
+++ b/devtools/client/debugger/new/src/utils/breakpoint/index.js
@@ -4,12 +4,15 @@
// @flow
+import { sortBy } from "lodash";
+
import { getBreakpoint } from "../../selectors";
import assert from "../assert";
import { features } from "../prefs";
export { getASTLocation, findScopeByName } from "./astBreakpointLocation";
+import type { FormattedBreakpoint } from "../../selectors/breakpointSources";
import type {
Location,
PendingLocation,
@@ -179,3 +182,20 @@ export function createPendingBreakpoint(bp: Breakpoint) {
generatedLocation: pendingGeneratedLocation
};
}
+
+export function sortBreakpoints(breakpoints: FormattedBreakpoint[]) {
+ breakpoints = breakpoints.map(bp => ({
+ ...bp,
+ selectedLocation: {
+ ...bp.selectedLocation,
+ // If a breakpoint has an undefined column, we must provide a 0 value
+ // or the breakpoint will display after all explicit column numbers
+ column: bp.selectedLocation.column || 0
+ }
+ }));
+
+ return sortBy(breakpoints, [
+ "selectedLocation.line",
+ "selectedLocation.column"
+ ]);
+}
diff --git a/devtools/client/debugger/new/src/utils/dbg.js b/devtools/client/debugger/new/src/utils/dbg.js
index bedcad7e5d32..e6c0f05cb20c 100644
--- a/devtools/client/debugger/new/src/utils/dbg.js
+++ b/devtools/client/debugger/new/src/utils/dbg.js
@@ -54,6 +54,14 @@ function _formatPausePoints(dbg: Object, url: string) {
console.log(formatPausePoints(source.text, pausePoints));
}
+function _formatColumnBreapoints(dbg: Object) {
+ console.log(
+ dbg.selectors.formatColumnBreakpoints(
+ dbg.selectors.visibleColumnBreakpoints()
+ )
+ );
+}
+
export function setupHelper(obj: Object) {
const selectors = bindSelectors(obj);
const dbg: Object = {
@@ -72,7 +80,8 @@ export function setupHelper(obj: Object) {
sendPacket: (packet, cbk) => sendPacket(dbg, packet, cbk)
},
formatters: {
- pausePoints: url => _formatPausePoints(dbg, url)
+ pausePoints: url => _formatPausePoints(dbg, url),
+ visibleColumnBreakpoints: () => _formatColumnBreapoints(dbg)
},
_telemetry: {
events: {}
diff --git a/devtools/client/debugger/new/src/utils/editor/index.js b/devtools/client/debugger/new/src/utils/editor/index.js
index 5acdaea8a76b..d6a8bd811865 100644
--- a/devtools/client/debugger/new/src/utils/editor/index.js
+++ b/devtools/client/debugger/new/src/utils/editor/index.js
@@ -158,6 +158,34 @@ function isVisible(codeMirror: any, top: number, left: number) {
return inXView && inYView;
}
+export function getLocationsInViewport(_editor: any) {
+ // Get scroll position
+ const charWidth = _editor.codeMirror.defaultCharWidth();
+ const scrollArea = _editor.codeMirror.getScrollInfo();
+ const { scrollLeft } = _editor.codeMirror.doc;
+ const rect = _editor.codeMirror.getWrapperElement().getBoundingClientRect();
+ const topVisibleLine = _editor.codeMirror.lineAtHeight(rect.top, "window");
+ const bottomVisibleLine = _editor.codeMirror.lineAtHeight(
+ rect.bottom,
+ "window"
+ );
+
+ const leftColumn = Math.floor(scrollLeft > 0 ? scrollLeft / charWidth : 0);
+ const rightPosition = scrollLeft + (scrollArea.clientWidth - 30);
+ const rightCharacter = Math.floor(rightPosition / charWidth);
+
+ return {
+ start: {
+ line: topVisibleLine,
+ column: leftColumn
+ },
+ end: {
+ line: bottomVisibleLine,
+ column: rightCharacter
+ }
+ };
+}
+
export function markText(_editor: any, className, { start, end }: EditorRange) {
return _editor.codeMirror.markText(
{ ch: start.column, line: start.line },
diff --git a/devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints-actions.js b/devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints-actions.js
index 2829db2e0407..a9bc68e8c99d 100644
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints-actions.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints-actions.js
@@ -33,38 +33,46 @@ add_task(async function() {
await addBreakpoint(dbg, "simple1", 5);
await addBreakpoint(dbg, "simple1", 6);
- openFirstBreakpointContextMenu(dbg)
+ openFirstBreakpointContextMenu(dbg);
// select "Disable Others"
+ let dispatched = waitForDispatch(dbg, "DISABLE_BREAKPOINT", 3);
selectMenuItem(dbg, 7);
await waitForState(dbg, state =>
dbg.selectors.getBreakpointsList(state)
.every(bp => (bp.location.line !== 1) === bp.disabled)
);
+ await dispatched;
ok("breakpoint at 1 is the only enabled breakpoint");
- openFirstBreakpointContextMenu(dbg)
+ openFirstBreakpointContextMenu(dbg);
// select "Disable All"
+ dispatched = waitForDispatch(dbg, "DISABLE_ALL_BREAKPOINTS");
selectMenuItem(dbg, 9);
await waitForState(dbg, state =>
dbg.selectors.getBreakpointsList(state).every(bp => bp.disabled)
);
- ok("all breakpoints are disabled")
+ await dispatched;
+ ok("all breakpoints are disabled");
- openFirstBreakpointContextMenu(dbg)
+ openFirstBreakpointContextMenu(dbg);
// select "Enable Others"
+ dispatched = waitForDispatch(dbg, "ENABLE_BREAKPOINT", 3);
selectMenuItem(dbg, 3);
await waitForState(dbg, state =>
dbg.selectors.getBreakpointsList(state)
.every(bp => (bp.location.line === 1) === bp.disabled)
);
+ await dispatched;
ok("all breakpoints except line 1 are enabled");
- openFirstBreakpointContextMenu(dbg)
+ openFirstBreakpointContextMenu(dbg);
// select "Remove Others"
+ dispatched = waitForDispatch(dbg, "REMOVE_BREAKPOINT", 3);
selectMenuItem(dbg, 6);
await waitForState(dbg, state =>
dbg.selectors.getBreakpointsList(state).length === 1 &&
dbg.selectors.getBreakpointsList(state)[0].location.line === 1
);
+ await dispatched;
ok("remaining breakpoint should be on line 1");
});
diff --git a/devtools/client/debugger/new/test/mochitest/helpers.js b/devtools/client/debugger/new/test/mochitest/helpers.js
index 1b1a95873463..6009dbf23cde 100644
--- a/devtools/client/debugger/new/test/mochitest/helpers.js
+++ b/devtools/client/debugger/new/test/mochitest/helpers.js
@@ -341,7 +341,7 @@ function assertDebugLine(dbg, line) {
const markedSpans = lineInfo.handle.markedSpans;
if (markedSpans && markedSpans.length > 0) {
const classMatch = markedSpans.filter(
- span => span.marker.className.includes("debug-expression")
+ span => span.marker.className && span.marker.className.includes("debug-expression")
).length > 0;
ok(
diff --git a/devtools/client/shared/components/reps/images/input.svg b/devtools/client/shared/components/reps/images/input.svg
new file mode 100644
index 000000000000..830b651e9e02
--- /dev/null
+++ b/devtools/client/shared/components/reps/images/input.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/devtools/client/shared/components/reps/images/moz.build b/devtools/client/shared/components/reps/images/moz.build
index 180e133adf7b..4cc1ee9e94a0 100644
--- a/devtools/client/shared/components/reps/images/moz.build
+++ b/devtools/client/shared/components/reps/images/moz.build
@@ -5,6 +5,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DevToolsModules(
+ 'input.svg',
'jump-definition.svg',
'open-inspector.svg',
)
diff --git a/devtools/client/shared/components/reps/reps.css b/devtools/client/shared/components/reps/reps.css
index 52f698b9f2ac..ce0b4ae153cc 100644
--- a/devtools/client/shared/components/reps/reps.css
+++ b/devtools/client/shared/components/reps/reps.css
@@ -276,6 +276,22 @@ button.jump-definition {
background-color: var(--theme-highlight-blue);
}
+/******************************************************************************/
+/* Invoke getter button */
+
+button.invoke-getter {
+ mask: url("resource://devtools/client/shared/components/reps/images/input.svg") no-repeat;
+ display: inline-block;
+ background-color: var(--comment-node-color);
+ height: 12px;
+ vertical-align:bottom;
+ border:none;
+}
+
+.invoke-getter:hover {
+ background-color: var(--theme-highlight-blue);
+}
+
/******************************************************************************/
/* "more…" ellipsis */
.more-ellipsis {
@@ -337,24 +353,29 @@ button.jump-definition {
cursor: default;
}
-.tree-node img.arrow {
- mask: url("resource://devtools/client/debugger/new/images/arrow.svg") no-repeat;
- mask-size: 100%;
+.tree-node button.arrow {
+ background:url("resource://devtools/client/debugger/new/images/arrow.svg") no-repeat;
+ background-size:contain;
+ background-position:center center;
width: 9px;
height: 9px;
+ border:0;
+ padding:0;
margin-inline-start: 1px;
margin-inline-end: 4px;
- background-color: var(--theme-splitter-color, #9B9B9B);
transform: rotate(-90deg);
+ transform-origin: center center;
transition: transform 0.125s ease;
align-self: center;
+ -moz-context-properties: fill;
+ fill: var(--theme-splitter-color, #9B9B9B);
}
-html[dir="rtl"] .tree-node img.arrow {
+html[dir="rtl"] .tree-node button.arrow {
transform: rotate(90deg);
}
-.tree-node img.arrow.expanded.expanded {
+.tree-node button.arrow.expanded.expanded {
transform: rotate(0deg);
}
@@ -363,8 +384,8 @@ html[dir="rtl"] .tree-node img.arrow {
background-color: var(--theme-selection-background, #0a84ff);
}
-.tree-node.focused img.arrow {
- background-color: currentColor;
+.tree-node.focused button.arrow {
+ fill: currentColor;
}
/* 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
@@ -404,7 +425,7 @@ html[dir="rtl"] .tree-node img.arrow {
color: var(--theme-comment);
}
-.object-inspector .tree-node img.arrow {
+.object-inspector .tree-node .arrow {
display: inline-block;
vertical-align: middle;
}
diff --git a/devtools/client/shared/components/reps/reps.js b/devtools/client/shared/components/reps/reps.js
index 86ce7479a4db..b0313801c8dc 100644
--- a/devtools/client/shared/components/reps/reps.js
+++ b/devtools/client/shared/components/reps/reps.js
@@ -3771,7 +3771,7 @@ class ArrowExpander extends Component {
if (expanded) {
classNames.push("expanded");
}
- return _reactDomFactories2.default.img({
+ return _reactDomFactories2.default.button({
className: classNames.join(" ")
});
}
@@ -4993,6 +4993,8 @@ module.exports = {
"use strict";
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
+
/* 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 . */
@@ -5014,18 +5016,40 @@ Accessor.propTypes = {
};
function Accessor(props) {
- const { object } = props;
+ const { object, evaluation, onInvokeGetterButtonClick } = props;
+
+ if (evaluation) {
+ const { Rep, Grip } = __webpack_require__(3647);
+ return span({
+ className: "objectBox objectBox-accessor objectTitle"
+ }, Rep(_extends({}, props, {
+ object: evaluation.getterValue,
+ mode: props.mode || MODE.TINY,
+ defaultRep: Grip
+ })));
+ }
+
+ if (hasGetter(object) && onInvokeGetterButtonClick) {
+ return dom.button({
+ className: "invoke-getter",
+ title: "Invoke getter",
+ onClick: event => {
+ onInvokeGetterButtonClick();
+ event.stopPropagation();
+ }
+ });
+ }
const accessors = [];
if (hasGetter(object)) {
accessors.push("Getter");
}
+
if (hasSetter(object)) {
accessors.push("Setter");
}
- const title = accessors.join(" & ");
- return span({ className: "objectBox objectBox-accessor objectTitle" }, title);
+ return span({ className: "objectBox objectBox-accessor objectTitle" }, accessors.join(" & "));
}
function hasGetter(object) {
diff --git a/devtools/client/shared/vendor/WASMPARSER_UPGRADING b/devtools/client/shared/vendor/WASMPARSER_UPGRADING
index 88caa491899d..59db3a8cd2d1 100644
--- a/devtools/client/shared/vendor/WASMPARSER_UPGRADING
+++ b/devtools/client/shared/vendor/WASMPARSER_UPGRADING
@@ -1,13 +1,13 @@
# wasmparser version
-Current vesion is: 0.6.1
+Current vesion is: 0.6.2
# Upgrade process
1. Pull latest release from npm and extract WasmDis.js and WasmParser.js, e.g.
```
-curl https://registry.npmjs.org/wasmparser/-/wasmparser-0.6.1.tgz | tar -x --strip-components 2 package/dist/{WasmDis,WasmParser}.js
+curl https://registry.npmjs.org/wasmparser/-/wasmparser-0.6.2.tgz | tar -x --strip-components 2 package/dist/{WasmDis,WasmParser}.js
```
2. Remove reference to source maps (last line)
diff --git a/devtools/client/shared/vendor/WasmDis.js b/devtools/client/shared/vendor/WasmDis.js
index e84b2b975769..82574b2724cb 100644
--- a/devtools/client/shared/vendor/WasmDis.js
+++ b/devtools/client/shared/vendor/WasmDis.js
@@ -631,7 +631,7 @@ var WasmDisassembler = /** @class */ (function () {
this.appendBuffer(" " + operator.literal.toString());
break;
case 66 /* i64_const */:
- this.appendBuffer(" " + operator.literal.toDouble());
+ this.appendBuffer(" " + operator.literal.toString());
break;
case 67 /* f32_const */:
this.appendBuffer(" " + formatFloat32(operator.literal));
diff --git a/devtools/client/shared/vendor/WasmParser.js b/devtools/client/shared/vendor/WasmParser.js
index 5852ede7c4b2..71b9afc11fce 100644
--- a/devtools/client/shared/vendor/WasmParser.js
+++ b/devtools/client/shared/vendor/WasmParser.js
@@ -414,6 +414,36 @@ var Int64 = /** @class */ (function () {
}
return sum;
};
+ Int64.prototype.toString = function () {
+ var low = (this._data[0] | (this._data[1] << 8) | (this._data[2] << 16) | (this._data[3] << 24)) >>> 0;
+ var high = (this._data[4] | (this._data[5] << 8) | (this._data[6] << 16) | (this._data[7] << 24)) >>> 0;
+ if (low === 0 && high === 0) {
+ return '0';
+ }
+ var sign = false;
+ if (high >> 31) {
+ high = 4294967296 - high;
+ if (low > 0) {
+ high--;
+ low = 4294967296 - low;
+ }
+ sign = true;
+ }
+ var buf = [];
+ while (high > 0) {
+ var t = ((high % 10) * 4294967296) + low;
+ high = Math.floor(high / 10);
+ buf.unshift((t % 10).toString());
+ low = Math.floor(t / 10);
+ }
+ while (low > 0) {
+ buf.unshift((low % 10).toString());
+ low = Math.floor(low / 10);
+ }
+ if (sign)
+ buf.unshift('-');
+ return buf.join('');
+ };
Object.defineProperty(Int64.prototype, "data", {
get: function () {
return this._data;