Backed out changeset 91e1fe27cef9 (bug 1511352) for causing merge conflicts with bug 820878 a=backout
authorCoroiu Cristina <ccoroiu@mozilla.com>
Sat, 01 Dec 2018 07:44:09 +0200
changeset 505488 a00c3f2302035bb9d304572b4458f6e9dfd94f1e
parent 505487 7a80928fff2952f4cc1839b6af341fde892d7464
child 505489 925a2727cc3755bb0d0683d696b8d965b16e7236
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs1511352, 820878
milestone65.0a1
backs out91e1fe27cef95ba156878d94952d2052e023ef41
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset 91e1fe27cef9 (bug 1511352) for causing merge conflicts with bug 820878 a=backout
devtools/client/debugger/new/README.mozilla
devtools/client/debugger/new/dist/debugger.css
devtools/client/debugger/new/dist/parser-worker.js
devtools/client/debugger/new/dist/vendors.js
devtools/client/debugger/new/images/arrow.svg
devtools/client/debugger/new/images/column-marker.svg
devtools/client/debugger/new/images/moz.build
devtools/client/debugger/new/src/actions/ast.js
devtools/client/debugger/new/src/actions/ast/moz.build
devtools/client/debugger/new/src/actions/ast/setPausePoints.js
devtools/client/debugger/new/src/actions/breakpoints/addBreakpoint.js
devtools/client/debugger/new/src/actions/breakpoints/index.js
devtools/client/debugger/new/src/actions/breakpoints/syncBreakpoint.js
devtools/client/debugger/new/src/actions/index.js
devtools/client/debugger/new/src/actions/moz.build
devtools/client/debugger/new/src/actions/preview.js
devtools/client/debugger/new/src/actions/sources/newSources.js
devtools/client/debugger/new/src/actions/sources/select.js
devtools/client/debugger/new/src/actions/utils/middleware/promise.js
devtools/client/debugger/new/src/actions/utils/moz.build
devtools/client/debugger/new/src/client/firefox/commands.js
devtools/client/debugger/new/src/client/firefox/create.js
devtools/client/debugger/new/src/client/firefox/events.js
devtools/client/debugger/new/src/components/Editor/ColumnBreakpoint.js
devtools/client/debugger/new/src/components/Editor/Footer.js
devtools/client/debugger/new/src/components/Editor/HighlightLine.js
devtools/client/debugger/new/src/components/Editor/index.js
devtools/client/debugger/new/src/components/ProjectSearch.js
devtools/client/debugger/new/src/components/QuickOpenModal.js
devtools/client/debugger/new/src/components/SecondaryPanes/Breakpoints/Breakpoint.js
devtools/client/debugger/new/src/components/SecondaryPanes/index.js
devtools/client/debugger/new/src/components/SecondaryPanes/moz.build
devtools/client/debugger/new/src/reducers/ast.js
devtools/client/debugger/new/src/reducers/breakpoints.js
devtools/client/debugger/new/src/reducers/index.js
devtools/client/debugger/new/src/reducers/moz.build
devtools/client/debugger/new/src/reducers/sources.js
devtools/client/debugger/new/src/reducers/tabs.js
devtools/client/debugger/new/src/reducers/ui.js
devtools/client/debugger/new/src/selectors/breakpointSources.js
devtools/client/debugger/new/src/selectors/index.js
devtools/client/debugger/new/src/selectors/visibleColumnBreakpoints.js
devtools/client/debugger/new/src/selectors/visibleSelectedFrame.js
devtools/client/debugger/new/src/utils/ast.js
devtools/client/debugger/new/src/utils/bootstrap.js
devtools/client/debugger/new/src/utils/breakpoint/astBreakpointLocation.js
devtools/client/debugger/new/src/utils/breakpoint/index.js
devtools/client/debugger/new/src/utils/dbg.js
devtools/client/debugger/new/src/utils/editor/get-expression.js
devtools/client/debugger/new/src/utils/editor/get-token-location.js
devtools/client/debugger/new/src/utils/editor/index.js
devtools/client/debugger/new/src/utils/location.js
devtools/client/debugger/new/src/utils/log.js
devtools/client/debugger/new/src/utils/pause/mapScopes/getApplicableBindingsForOriginalPosition.js
devtools/client/debugger/new/src/utils/pause/mapScopes/index.js
devtools/client/debugger/new/src/utils/pause/mapScopes/locColumn.js
devtools/client/debugger/new/src/utils/pause/mapScopes/mappingContains.js
devtools/client/debugger/new/src/utils/pause/mapScopes/positionCmp.js
devtools/client/debugger/new/src/utils/pause/mapScopes/rangeMetadata.js
devtools/client/debugger/new/src/utils/pause/pausePoints.js
devtools/client/debugger/new/src/utils/pause/stepping.js
devtools/client/debugger/new/src/utils/prefs.js
devtools/client/debugger/new/src/utils/quick-open.js
devtools/client/debugger/new/src/utils/source-maps.js
devtools/client/debugger/new/src/utils/source.js
devtools/client/debugger/new/src/workers/parser/getScopes/index.js
devtools/client/debugger/new/src/workers/parser/index.js
devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints-actions.js
devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints-cond.js
devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints-reloading.js
devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints.js
devtools/client/debugger/new/test/mochitest/browser_dbg-console-async.js
devtools/client/debugger/new/test/mochitest/browser_dbg-console.js
devtools/client/debugger/new/test/mochitest/browser_dbg-editor-gutter.js
devtools/client/debugger/new/test/mochitest/browser_dbg-editor-highlight.js
devtools/client/debugger/new/test/mochitest/browser_dbg-editor-mode.js
devtools/client/debugger/new/test/mochitest/browser_dbg-keyboard-navigation.js
devtools/client/debugger/new/test/mochitest/browser_dbg-minified.js
devtools/client/debugger/new/test/mochitest/browser_dbg-outline-filter.js
devtools/client/debugger/new/test/mochitest/browser_dbg-outline-pretty.js
devtools/client/debugger/new/test/mochitest/browser_dbg-outline.js
devtools/client/debugger/new/test/mochitest/browser_dbg-pause-points.js
devtools/client/debugger/new/test/mochitest/browser_dbg-pretty-print-paused.js
devtools/client/debugger/new/test/mochitest/browser_dbg-pretty-print.js
devtools/client/debugger/new/test/mochitest/browser_dbg-preview-source-maps.js
devtools/client/debugger/new/test/mochitest/browser_dbg-preview.js
devtools/client/debugger/new/test/mochitest/browser_dbg-quick-open.js
devtools/client/debugger/new/test/mochitest/browser_dbg-react-app.js
devtools/client/debugger/new/test/mochitest/browser_dbg-reloading.js
devtools/client/debugger/new/test/mochitest/browser_dbg-search-file.js
devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemaps.js
devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemaps2.js
devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemaps3.js
devtools/client/debugger/new/test/mochitest/browser_dbg-sources-arrow-keys.js
devtools/client/debugger/new/test/mochitest/browser_dbg-sources-named-eval.js
devtools/client/debugger/new/test/mochitest/browser_dbg-sources-querystring.js
devtools/client/debugger/new/test/mochitest/browser_dbg-sources.js
devtools/client/debugger/new/test/mochitest/browser_dbg-tabs-pretty-print.js
devtools/client/debugger/new/test/mochitest/browser_dbg-tabs.js
devtools/client/debugger/new/test/mochitest/browser_dbg-toggling-tools.js
devtools/client/debugger/new/test/mochitest/browser_dbg-xhr-breakpoints.js
devtools/client/debugger/new/test/mochitest/helpers.js
devtools/client/locales/en-US/debugger.properties
devtools/client/preferences/debugger.js
devtools/client/shared/components/reps/reps.js
--- a/devtools/client/debugger/new/README.mozilla
+++ b/devtools/client/debugger/new/README.mozilla
@@ -1,13 +1,13 @@
 This is the debugger.html project output.
 See https://github.com/devtools-html/debugger.html
 
-Version 106
+Version 105
 
-Comparison: https://github.com/devtools-html/debugger.html/compare/release-105...release-106
+Comparison: https://github.com/devtools-html/debugger.html/compare/release-104...release-105
 
 Packages:
 - babel-plugin-transform-es2015-modules-commonjs @6.26.2
 - babel-preset-react @6.24.1
 - react @16.4.1
 - react-dom @16.4.1
 - webpack @3.12.0
--- a/devtools/client/debugger/new/dist/debugger.css
+++ b/devtools/client/debugger/new/dist/debugger.css
@@ -2307,31 +2307,26 @@ menuseparator {
   background: var(--theme-body-color);
 }
 
 .source-footer > .commands > .blackboxed > img.blackBox {
   background: var(--theme-highlight-blue);
 }
 
 .source-footer .blackbox-summary,
-.source-footer .mapped-source,
-.source-footer .cursor-position {
+.source-footer .mapped-source {
   color: var(--theme-body-color);
   padding-left: 2.5px;
 }
 
 .source-footer .mapped-source {
   white-space: nowrap;
   overflow: hidden;
   text-overflow: ellipsis;
 }
-
-.source-footer .cursor-position {
-  padding: 5px;
-}
 /* 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/>. */
 
 .search-bar {
   display: flex;
   border: 1px solid transparent;
   border-top: 1px solid var(--theme-splitter-color);
@@ -2685,47 +2680,52 @@ menuseparator {
   font-size: 14px;
   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/>. */
 
 .call-site {
-  display: inline;
-}
-
-.call-site svg {
+  position: relative;
   display: inline;
   cursor: pointer;
-  height: 12px;
+}
+
+.call-site::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);
+  opacity: 0.5;
   width: 9px;
-  vertical-align: top;
-}
-
-.call-site.active svg {
-  fill: var(--blue-50);
-  stroke: var(--blue-60);
-}
-
-.call-site.disabled svg {
-  fill: var(--blue-50);
-  stroke: var(--blue-40);
-  fill-opacity: 0.5;
-}
-
-.theme-dark .call-site.active svg {
-  fill: var(--blue-55);
-  stroke: var(--blue-40);
-}
-
-.theme-dark .call-site.disabled svg {
-  fill: var(--blue-50);
-  stroke: var(--blue-60);
-  fill-opacity: 0.5;
+  height: 12px;
+}
+
+.call-site.active::before {
+  opacity: 1;
+}
+
+.theme-dark .call-site {
+  border-bottom: none;
+}
+
+.theme-dark .call-site-bp {
+  border-bottom: none;
+}
+
+.theme-dark .call-site::before {
+  background-color: var(--blue-60);
+  opacity: 1;
+}
+
+.theme-dark .call-site-bp::before {
+  background-color: var(--blue-50);
+  opacity: 0.5;
 }
 /* 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/>. */
 
 .conditional-breakpoint-panel {
   cursor: initial;
   margin: 1em 0;
@@ -2809,28 +2809,20 @@ menuseparator {
 }
 
 html[dir="rtl"] .editor-mount {
   direction: ltr;
 }
 
 .theme-light {
   --gutter-hover-background-color: #dde1e4;
-  --breakpoint-fill: var(--blue-50);
-  --breakpoint-stroke: var(--blue-60);
-  --breakpoint-fill-disabled: var(--blue-50);
-  --breakpoint-stroke-disabled: var(--blue-40);
 }
 
 .theme-dark {
   --gutter-hover-background-color: #414141;
-  --breakpoint-fill: var(--blue-55);
-  --breakpoint-stroke: var(--blue-40);
-  --breakpoint-fill-disabled: var(--blue-50);
-  --breakpoint-stroke-disabled: var(--blue-60);
 }
 
 :not(.empty-line):not(.new-breakpoint)
   > .CodeMirror-gutter-wrapper:hover
   > .CodeMirror-linenumber {
   height: 13px;
   color: var(--theme-body-color);
   /* Add 1px offset to the background to match it
@@ -2875,18 +2867,17 @@ html[dir="rtl"] .editor-mount {
   height: 14px;
 }
 
 .editor-wrapper .highlight-lines {
   background: var(--theme-selection-background-hover);
 }
 
 .editor.new-breakpoint svg {
-  fill: var(--breakpoint-fill);
-  stroke: var(--breakpoint-stroke);
+  fill: var(--theme-selection-background);
   width: 60px;
   height: 14px;
   position: absolute;
   top: 0px;
   right: -4px;
 }
 
 .inline-bp {
@@ -2903,25 +2894,22 @@ html[dir="rtl"] .editor-mount {
   position: absolute;
   right: -2px;
 }
 
 .editor.new-breakpoint.folding-enabled svg {
   right: -16px;
 }
 
-.new-breakpoint.has-condition .CodeMirror-gutter-wrapper svg {
+.new-breakpoint.has-condition svg {
   fill: var(--theme-graphs-yellow);
-  stroke: var(--theme-graphs-orange);
 }
 
 .editor.new-breakpoint.breakpoint-disabled svg {
-  fill: var(--breakpoint-fill-disabled);
-  stroke: var(--breakpoint-stroke-disabled);
-  fill-opacity: 0.5;
+  opacity: 0.3;
 }
 
 .editor.column-breakpoint svg {
   fill: var(--theme-selection-background);
   vertical-align: middle;
   width: 17px;
   height: 14px;
 }
@@ -3636,16 +3624,65 @@ html[dir="rtl"] .breakpoints-list .break
 
 :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
  * 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/>. */
 
+.event-listeners {
+  list-style: none;
+  margin: 0;
+  padding: 0;
+}
+
+.event-listeners .listener {
+  padding: 7px 10px 7px 21px;
+  clear: both;
+  overflow: hidden;
+}
+
+.event-listeners .listener * {
+  -moz-user-select: none;
+  user-select: none;
+}
+
+.event-listeners .listener:nth-of-type(2n) {
+  background-color: var(--theme-tab-toolbar-background);
+}
+
+.event-listeners .listener .type {
+  color: var(--theme-highlight-bluegrey);
+  padding-right: 5px;
+}
+
+.event-listeners .listener .selector {
+  color: var(--theme-content-color2);
+}
+
+.event-listeners .listener-checkbox {
+  margin-left: 0;
+}
+
+.event-listeners .listener .close-btn {
+  float: right;
+}
+
+.event-listeners .listener .close {
+  display: none;
+}
+
+.event-listeners .listener:hover .close {
+  display: block;
+}
+/* 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/>. */
+
 .workers-list * {
   user-select: none;
 }
 
 .workers-list .worker {
   font-size: 1rem;
   color: var(--theme-content-color1);
   padding: 0 1em;
--- a/devtools/client/debugger/new/dist/parser-worker.js
+++ b/devtools/client/debugger/new/dist/parser-worker.js
@@ -1003,43 +1003,47 @@ Object.defineProperty(exports, "__esModu
   value: true
 });
 exports.isFunction = isFunction;
 exports.isAwaitExpression = isAwaitExpression;
 exports.isYieldExpression = isYieldExpression;
 exports.isObjectShorthand = isObjectShorthand;
 exports.getObjectExpressionValue = getObjectExpressionValue;
 exports.getCode = getCode;
+exports.getVariableNames = getVariableNames;
 exports.getComments = getComments;
 exports.getSpecifiers = getSpecifiers;
+exports.isVariable = isVariable;
 exports.isComputedExpression = isComputedExpression;
 exports.getMemberExpression = getMemberExpression;
 exports.getVariables = getVariables;
 exports.getPatternIdentifiers = getPatternIdentifiers;
 exports.isTopLevel = isTopLevel;
 
 var _types = __webpack_require__(2268);
 
 var t = _interopRequireWildcard(_types);
 
 var _generator = __webpack_require__(2365);
 
 var _generator2 = _interopRequireDefault(_generator);
 
+var _flatten = __webpack_require__(706);
+
+var _flatten2 = _interopRequireDefault(_flatten);
+
 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
 
-/* 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/>. */
-
 function isFunction(node) {
   return t.isFunction(node) || t.isArrowFunctionExpression(node) || t.isObjectMethod(node) || t.isClassMethod(node);
-}
+} /* 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/>. */
 
 function isAwaitExpression(path) {
   const { node, parent } = path;
   return t.isAwaitExpression(node) || t.isAwaitExpression(parent.init) || t.isAwaitExpression(parent);
 }
 
 function isYieldExpression(path) {
   const { node, parent } = path;
@@ -1065,16 +1069,47 @@ function getObjectExpressionValue(node) 
   const shouldWrap = t.isObjectExpression(value);
   return shouldWrap ? `(${code})` : code;
 }
 
 function getCode(node) {
   return (0, _generator2.default)(node).code;
 }
 
+function getVariableNames(path) {
+  if (t.isObjectProperty(path.node) && !isFunction(path.node.value)) {
+    if (path.node.key.type === "StringLiteral") {
+      return [{
+        name: path.node.key.value,
+        location: path.node.loc
+      }];
+    } else if (path.node.value.type === "Identifier") {
+      return [{ name: path.node.value.name, location: path.node.loc }];
+    } else if (path.node.value.type === "AssignmentPattern") {
+      return [{ name: path.node.value.left.name, location: path.node.loc }];
+    }
+
+    return [{
+      name: path.node.key.name,
+      location: path.node.loc
+    }];
+  }
+
+  if (!path.node.declarations) {
+    return path.node.params.map(dec => ({
+      name: dec.name,
+      location: dec.loc
+    }));
+  }
+
+  const declarations = path.node.declarations.filter(dec => dec.id.type !== "ObjectPattern").map(getVariables);
+
+  return (0, _flatten2.default)(declarations);
+}
+
 function getComments(ast) {
   if (!ast || !ast.comments) {
     return [];
   }
   return ast.comments.map(comment => ({
     name: comment.location,
     location: comment.loc
   }));
@@ -1083,16 +1118,21 @@ function getComments(ast) {
 function getSpecifiers(specifiers) {
   if (!specifiers) {
     return [];
   }
 
   return specifiers.map(specifier => specifier.local && specifier.local.name);
 }
 
+function isVariable(path) {
+  const node = path.node;
+  return t.isVariableDeclaration(node) || isFunction(path) && path.node.params != null && path.node.params.length || t.isObjectProperty(node) && !isFunction(path.node.value);
+}
+
 function isComputedExpression(expression) {
   return (/^\[/m.test(expression)
   );
 }
 
 function getMemberExpression(root) {
   function _getMemberExpression(node, expr) {
     if (t.isMemberExpression(node)) {
@@ -1335,16 +1375,20 @@ function getFunctionParameterNames(path)
       }
     });
   }
   return [];
 }
 
 /* eslint-disable complexity */
 function extractSymbol(path, symbols) {
+  if ((0, _helpers.isVariable)(path)) {
+    symbols.variables.push(...(0, _helpers.getVariableNames)(path));
+  }
+
   if ((0, _helpers.isFunction)(path)) {
     symbols.functions.push({
       name: (0, _getFunctionName2.default)(path.node, path.parent),
       klass: (0, _inferClassName.inferClassName)(path),
       location: path.node.loc,
       parameterNames: getFunctionParameterNames(path),
       identifier: path.node.id
     });
@@ -1483,16 +1527,17 @@ function extractSymbol(path, symbols) {
   }
 }
 
 /* eslint-enable complexity */
 
 function extractSymbols(sourceId) {
   const symbols = {
     functions: [],
+    variables: [],
     callExpressions: [],
     memberExpressions: [],
     objectProperties: [],
     comments: [],
     identifiers: [],
     classes: [],
     imports: [],
     literals: [],
@@ -22922,27 +22967,25 @@ function onEnter(node, ancestors, state)
     return addEmptyPoint(state, startLocation);
   }
 }
 
 function hasPoint(state, { line, column }) {
   return state[line] && state[line][column];
 }
 
-function addPoint(state, location, types) {
+function addPoint(state, { line, column }, types) {
   if (typeof types === "boolean") {
     types = { step: types, break: types };
   }
 
-  const { line, column } = location;
-
   if (!state[line]) {
     state[line] = {};
   }
-  state[line][column] = { types, location };
+  state[line][column] = types;
   return state;
 }
 
 function addStopPoint(state, location) {
   return addPoint(state, location, { break: true, step: true });
 }
 
 function addEmptyPoint(state, location) {
@@ -46540,16 +46583,117 @@ module.exports = Symbol;
  */
 var isArray = Array.isArray;
 
 module.exports = isArray;
 
 
 /***/ }),
 
+/***/ 706:
+/***/ (function(module, exports, __webpack_require__) {
+
+var baseFlatten = __webpack_require__(707);
+
+/**
+ * Flattens `array` a single level deep.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Array
+ * @param {Array} array The array to flatten.
+ * @returns {Array} Returns the new flattened array.
+ * @example
+ *
+ * _.flatten([1, [2, [3, [4]], 5]]);
+ * // => [1, 2, [3, [4]], 5]
+ */
+function flatten(array) {
+  var length = array == null ? 0 : array.length;
+  return length ? baseFlatten(array, 1) : [];
+}
+
+module.exports = flatten;
+
+
+/***/ }),
+
+/***/ 707:
+/***/ (function(module, exports, __webpack_require__) {
+
+var arrayPush = __webpack_require__(287),
+    isFlattenable = __webpack_require__(708);
+
+/**
+ * The base implementation of `_.flatten` with support for restricting flattening.
+ *
+ * @private
+ * @param {Array} array The array to flatten.
+ * @param {number} depth The maximum recursion depth.
+ * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
+ * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
+ * @param {Array} [result=[]] The initial result value.
+ * @returns {Array} Returns the new flattened array.
+ */
+function baseFlatten(array, depth, predicate, isStrict, result) {
+  var index = -1,
+      length = array.length;
+
+  predicate || (predicate = isFlattenable);
+  result || (result = []);
+
+  while (++index < length) {
+    var value = array[index];
+    if (depth > 0 && predicate(value)) {
+      if (depth > 1) {
+        // Recursively flatten arrays (susceptible to call stack limits).
+        baseFlatten(value, depth - 1, predicate, isStrict, result);
+      } else {
+        arrayPush(result, value);
+      }
+    } else if (!isStrict) {
+      result[result.length] = value;
+    }
+  }
+  return result;
+}
+
+module.exports = baseFlatten;
+
+
+/***/ }),
+
+/***/ 708:
+/***/ (function(module, exports, __webpack_require__) {
+
+var Symbol = __webpack_require__(7),
+    isArguments = __webpack_require__(208),
+    isArray = __webpack_require__(70);
+
+/** Built-in value references. */
+var spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined;
+
+/**
+ * Checks if `value` is a flattenable `arguments` object or array.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
+ */
+function isFlattenable(value) {
+  return isArray(value) || isArguments(value) ||
+    !!(spreadableSymbol && value && value[spreadableSymbol]);
+}
+
+module.exports = isFlattenable;
+
+
+/***/ }),
+
 /***/ 71:
 /***/ (function(module, exports, __webpack_require__) {
 
 var isArray = __webpack_require__(70),
     isSymbol = __webpack_require__(72);
 
 /** Used to match property names within property paths. */
 var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
--- a/devtools/client/debugger/new/dist/vendors.js
+++ b/devtools/client/debugger/new/dist/vendors.js
@@ -4547,17 +4547,17 @@ var classNamesShape = exports.classNames
 
 module.exports = "<!-- 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/. --><svg viewBox=\"-1 73 16 11\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><g id=\"Shape-Copy-3-+-Shape-Copy-4\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(0.000000, 74.000000)\"><path d=\"M0.749321284,4.16081709 L4.43130681,0.242526751 C4.66815444,-0.00952143591 5.06030999,-0.0211407611 5.30721074,0.216574262 C5.55411149,0.454289284 5.56226116,0.851320812 5.32541353,1.103369 L1.95384971,4.69131519 L5.48809879,8.09407556 C5.73499955,8.33179058 5.74314922,8.72882211 5.50630159,8.9808703 C5.26945396,9.23291849 4.87729841,9.24453781 4.63039766,9.00682279 L0.827097345,5.34502101 C0.749816996,5.31670099 0.677016974,5.27216098 0.613753508,5.21125118 C0.427367989,5.03179997 0.377040713,4.7615583 0.465458792,4.53143559 C0.492371834,4.43667624 0.541703274,4.34676528 0.613628034,4.27022448 C0.654709457,4.22650651 0.70046335,4.19002189 0.749321284,4.16081709 Z\" id=\"Shape-Copy-3\" stroke=\"#FFFFFF\" stroke-width=\"0.05\" fill=\"#DDE1E4\"></path><path d=\"M13.7119065,5.44453032 L9.77062746,9.09174784 C9.51677479,9.3266604 9.12476399,9.31089603 8.89504684,9.05653714 C8.66532968,8.80217826 8.68489539,8.40554539 8.93874806,8.17063283 L12.5546008,4.82456128 L9.26827469,1.18571135 C9.03855754,0.931352463 9.05812324,0.534719593 9.31197591,0.299807038 C9.56582858,0.0648944831 9.95783938,0.0806588502 10.1875565,0.335017737 L13.72891,4.25625178 C13.8013755,4.28980469 13.8684335,4.3382578 13.9254821,4.40142604 C14.0883019,4.58171146 14.1258883,4.83347168 14.0435812,5.04846202 C14.0126705,5.15680232 13.9526426,5.2583679 13.8641331,5.34027361 C13.8174417,5.38348136 13.7660763,5.41820853 13.7119065,5.44453032 Z\" id=\"Shape-Copy-4\" stroke=\"#FFFFFF\" stroke-width=\"0.05\" fill=\"#DDE1E4\"></path></g></svg>"
 
 /***/ }),
 
 /***/ 348:
 /***/ (function(module, exports) {
 
-module.exports = "<!-- 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/. --><svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 16 16\" fill=\"context-fill #9B9B9B\"><path d=\"M8 13.4c-.5 0-.9-.2-1.2-.6L.4 5.2C0 4.7-.1 4.3.2 3.7S1 3 1.6 3h12.8c.6 0 1.2.1 1.4.7.3.6.2 1.1-.2 1.6l-6.4 7.6c-.3.4-.7.5-1.2.5z\"></path></svg>"
+module.exports = "<!-- 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/. --><svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 16 16\"><path d=\"M8 13.4c-.5 0-.9-.2-1.2-.6L.4 5.2C0 4.7-.1 4.3.2 3.7S1 3 1.6 3h12.8c.6 0 1.2.1 1.4.7.3.6.2 1.1-.2 1.6l-6.4 7.6c-.3.4-.7.5-1.2.5z\"></path></svg>"
 
 /***/ }),
 
 /***/ 349:
 /***/ (function(module, exports) {
 
 module.exports = "<!-- 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/. --><svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><g fill-rule=\"evenodd\"><circle cx=\"8\" cy=\"8.5\" r=\"1.5\"></circle><path d=\"M15.498 8.28l-.001-.03v-.002-.004l-.002-.018-.004-.031c0-.002 0-.002 0 0l-.004-.035.006.082c-.037-.296-.133-.501-.28-.661-.4-.522-.915-1.042-1.562-1.604-1.36-1.182-2.74-1.975-4.178-2.309a6.544 6.544 0 0 0-2.755-.042c-.78.153-1.565.462-2.369.91C3.252 5.147 2.207 6 1.252 7.035c-.216.233-.36.398-.499.577-.338.437-.338 1 0 1.437.428.552.941 1.072 1.59 1.635 1.359 1.181 2.739 1.975 4.177 2.308.907.21 1.829.223 2.756.043.78-.153 1.564-.462 2.369-.91 1.097-.612 2.141-1.464 3.097-2.499.217-.235.36-.398.498-.578.12-.128.216-.334.248-.554 0 .01 0 .01-.008.04l.013-.079-.001.011.003-.031.001-.017v.005l.001-.02v.008l.002-.03.001-.05-.001-.044v-.004-.004zm-.954.045v.007l.001.004V8.33v.012l-.001.01v-.005-.005l.002-.015-.001.008c-.002.014-.002.014 0 0l-.007.084c.003-.057-.004-.041-.014-.031-.143.182-.27.327-.468.543-.89.963-1.856 1.752-2.86 2.311-.724.404-1.419.677-2.095.81a5.63 5.63 0 0 1-2.374-.036c-1.273-.295-2.523-1.014-3.774-2.101-.604-.525-1.075-1.001-1.457-1.496-.054-.07-.054-.107 0-.177.117-.152.244-.298.442-.512.89-.963 1.856-1.752 2.86-2.311.724-.404 1.419-.678 2.095-.81a5.631 5.631 0 0 1 2.374.036c1.272.295 2.523 1.014 3.774 2.101.603.524 1.074 1 1.457 1.496.035.041.043.057.046.076 0 .01 0 .01.008.043l-.009-.047.003.02-.002-.013v-.008.016c0-.004 0-.004 0 0v-.004z\"></path></g></svg>"
 
@@ -8428,17 +8428,17 @@ function createStructuredSelector(select
   });
 }
 
 /***/ }),
 
 /***/ 3801:
 /***/ (function(module, exports) {
 
-module.exports = "<svg viewBox=\"0 0 9 12\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><g id=\"columnmarkergroup\" stroke-width=\"1\" fill-rule=\"evenodd\"><polygon id=\"columnmarker\" points=\"0 0 4 0 9 6 4 12 0 12\"></polygon></g></svg>"
+module.exports = "<svg viewBox=\"0 0 9 12\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><g id=\"columnmarkergroup\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\"><polygon id=\"columnmarker\" fill=\"#1B1B1D\" points=\"0 0 4 0 9 6 4 12 0 12\"></polygon></g></svg>"
 
 /***/ }),
 
 /***/ 3802:
 /***/ (function(module, exports, __webpack_require__) {
 
 const SplitBox = __webpack_require__(3803);
 
--- a/devtools/client/debugger/new/images/arrow.svg
+++ b/devtools/client/debugger/new/images/arrow.svg
@@ -1,6 +1,6 @@
 <!-- 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/. -->
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16" fill="context-fill #9B9B9B">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16">
   <path d="M8 13.4c-.5 0-.9-.2-1.2-.6L.4 5.2C0 4.7-.1 4.3.2 3.7S1 3 1.6 3h12.8c.6 0 1.2.1 1.4.7.3.6.2 1.1-.2 1.6l-6.4 7.6c-.3.4-.7.5-1.2.5z"/>
 </svg>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/devtools/client/debugger/new/images/column-marker.svg
@@ -0,0 +1,5 @@
+<svg width="9px" height="12px" viewBox="0 0 9 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <g id="columnmarkergroup" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <polygon id="columnmarker" fill="#1B1B1D" points="0 0 4 0 9 6 4 12 0 12"></polygon>
+    </g>
+</svg>
\ No newline at end of file
--- a/devtools/client/debugger/new/images/moz.build
+++ b/devtools/client/debugger/new/images/moz.build
@@ -7,16 +7,17 @@
 
 DevToolsModules(
     'angular.svg',
     'arrow.svg',
     'blackBox.svg',
     'breakpoint.svg',
     'close.svg',
     'coffeescript.svg',
+    'column-marker.svg',
     'command-chevron.svg',
     'disable-pausing.svg',
     'domain.svg',
     'extension.svg',
     'file.svg',
     'folder.svg',
     'help.svg',
     'javascript.svg',
--- a/devtools/client/debugger/new/src/actions/ast.js
+++ b/devtools/client/debugger/new/src/actions/ast.js
@@ -13,27 +13,27 @@ import {
 } from "../selectors";
 
 import { mapFrames, fetchExtra } from "./pause";
 import { updateTab } from "./tabs";
 
 import { PROMISE } from "./utils/middleware/promise";
 
 import { setInScopeLines } from "./ast/setInScopeLines";
-import { setPausePoints } from "./ast/setPausePoints";
-export { setPausePoints };
-
+import { updateSymbolLocations } from "./utils/symbols";
 import {
   getSymbols,
   findOutOfScopeLocations,
   getFramework,
+  getPausePoints,
   type AstPosition
 } from "../workers/parser";
 
-import { isLoaded } from "../utils/source";
+import { features } from "../utils/prefs";
+import { isLoaded, isGenerated } from "../utils/source";
 
 import type { SourceId } from "../types";
 import type { ThunkArgs, Action } from "./types";
 
 export function setSourceMetaData(sourceId: SourceId) {
   return async ({ dispatch, getState }: ThunkArgs) => {
     const source = getSource(getState(), sourceId);
     if (!source || !isLoaded(source) || source.isWasm) {
@@ -63,17 +63,25 @@ export function setSymbols(sourceId: Sou
 
     if (source.isWasm || hasSymbols(getState(), source) || !isLoaded(source)) {
       return;
     }
 
     await dispatch({
       type: "SET_SYMBOLS",
       sourceId,
-      [PROMISE]: getSymbols(sourceId)
+      [PROMISE]: (async function() {
+        const symbols = await getSymbols(sourceId);
+        const mappedSymbols = updateSymbolLocations(
+          symbols,
+          source,
+          sourceMaps
+        );
+        return mappedSymbols;
+      })()
     });
 
     if (isPaused(getState())) {
       await dispatch(fetchExtra());
       await dispatch(mapFrames());
     }
 
     await dispatch(setPausePoints(sourceId));
@@ -102,8 +110,50 @@ export function setOutOfScopeLocations()
       ({
         type: "OUT_OF_SCOPE_LOCATIONS",
         locations
       }: Action)
     );
     dispatch(setInScopeLines());
   };
 }
+
+function compressPausePoints(pausePoints) {
+  const compressed = {};
+  for (const line in pausePoints) {
+    compressed[line] = {};
+    for (const col in pausePoints[line]) {
+      const point = pausePoints[line][col];
+      compressed[line][col] = (point.break ? 1 : 0) | (point.step ? 2 : 0);
+    }
+  }
+
+  return compressed;
+}
+
+export function setPausePoints(sourceId: SourceId) {
+  return async ({ dispatch, getState, client }: ThunkArgs) => {
+    const source = getSourceFromId(getState(), sourceId);
+    if (!features.pausePoints || !source || !source.text) {
+      return;
+    }
+
+    if (source.isWasm) {
+      return;
+    }
+
+    const pausePoints = await getPausePoints(sourceId);
+    const compressed = compressPausePoints(pausePoints);
+
+    if (isGenerated(source)) {
+      await client.setPausePoints(sourceId, compressed);
+    }
+
+    dispatch(
+      ({
+        type: "SET_PAUSE_POINTS",
+        sourceText: source.text || "",
+        sourceId,
+        pausePoints
+      }: Action)
+    );
+  };
+}
--- a/devtools/client/debugger/new/src/actions/ast/moz.build
+++ b/devtools/client/debugger/new/src/actions/ast/moz.build
@@ -4,10 +4,9 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DIRS += [
 
 ]
 
 DebuggerModules(
     'setInScopeLines.js',
-    'setPausePoints.js',
 )
deleted file mode 100644
--- a/devtools/client/debugger/new/src/actions/ast/setPausePoints.js
+++ /dev/null
@@ -1,66 +0,0 @@
-/* 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/>. */
-
-import { getSourceFromId } from "../../selectors";
-import * as parser from "../../workers/parser";
-import { isGenerated } from "../../utils/source";
-import { mapPausePoints } from "../../utils/pause/pausePoints";
-import { features } from "../../utils/prefs";
-
-import type { SourceId } from "../types";
-import type { ThunkArgs, Action } from "./types";
-
-function compressPausePoints(pausePoints) {
-  const compressed = {};
-  for (const line in pausePoints) {
-    compressed[line] = {};
-    for (const col in pausePoints[line]) {
-      const { types } = pausePoints[line][col];
-      compressed[line][col] = (types.break ? 1 : 0) | (types.step ? 2 : 0);
-    }
-  }
-
-  return compressed;
-}
-
-async function mapLocations(pausePoints, source, sourceMaps) {
-  const sourceId = source.id;
-  return mapPausePoints(pausePoints, async ({ types, location }) => {
-    const generatedLocation = await sourceMaps.getGeneratedLocation(
-      { ...location, sourceId },
-      source
-    );
-
-    return { types, location, generatedLocation };
-  });
-}
-export function setPausePoints(sourceId: SourceId) {
-  return async ({ dispatch, getState, client, sourceMaps }: ThunkArgs) => {
-    const source = getSourceFromId(getState(), sourceId);
-    if (!features.pausePoints || !source || !source.text) {
-      return;
-    }
-
-    if (source.isWasm) {
-      return;
-    }
-
-    let pausePoints = await parser.getPausePoints(sourceId);
-    pausePoints = await mapLocations(pausePoints, source, sourceMaps);
-
-    if (isGenerated(source)) {
-      const compressed = compressPausePoints(pausePoints);
-      await client.setPausePoints(sourceId, compressed);
-    }
-
-    dispatch(
-      ({
-        type: "SET_PAUSE_POINTS",
-        sourceText: source.text || "",
-        sourceId,
-        pausePoints
-      }: Action)
-    );
-  };
-}
--- a/devtools/client/debugger/new/src/actions/breakpoints/addBreakpoint.js
+++ b/devtools/client/debugger/new/src/actions/breakpoints/addBreakpoint.js
@@ -89,31 +89,31 @@ async function addBreakpointPromise(getS
 
 /**
  * Add a new hidden breakpoint
  *
  * @memberOf actions/breakpoints
  * @param location
  * @return {function(ThunkArgs)}
  */
-export function addHiddenBreakpoint(location: SourceLocation) {
+export function addHiddenBreakpoint(location: Location) {
   return ({ dispatch }: ThunkArgs) => {
     return dispatch(addBreakpoint(location, { hidden: true }));
   };
 }
 
 /**
  * Enabling a breakpoint
  * will reuse the existing breakpoint information that is stored.
  *
  * @memberof actions/breakpoints
  * @static
- * @param {SourceLocation} $1.location Location  value
+ * @param {Location} $1.location Location  value
  */
-export function enableBreakpoint(location: SourceLocation) {
+export function enableBreakpoint(location: Location) {
   return async ({ dispatch, getState, client, sourceMaps }: ThunkArgs) => {
     const breakpoint = getBreakpoint(getState(), location);
     if (!breakpoint || breakpoint.loading) {
       return;
     }
 
     // To instantly reflect in the UI, we optimistically enable the breakpoint
     const enabledBreakpoint = {
@@ -134,17 +134,17 @@ export function enableBreakpoint(locatio
  *
  * @memberof actions/breakpoints
  * @static
  * @param {String} $1.condition Conditional breakpoint condition value
  * @param {Boolean} $1.disabled Disable value for breakpoint value
  */
 
 export function addBreakpoint(
-  location: SourceLocation,
+  location: Location,
   { condition, hidden }: addBreakpointOptions = {}
 ) {
   const breakpoint = createBreakpoint(location, { condition, hidden });
   return ({ dispatch, getState, sourceMaps, client }: ThunkArgs) => {
     recordEvent("add_breakpoint");
 
     return dispatch({
       type: "ADD_BREAKPOINT",
--- a/devtools/client/debugger/new/src/actions/breakpoints/index.js
+++ b/devtools/client/debugger/new/src/actions/breakpoints/index.js
@@ -27,32 +27,32 @@ import {
 } from "./addBreakpoint";
 import remapLocations from "./remapLocations";
 import { syncBreakpoint } from "./syncBreakpoint";
 import { isEmptyLineInSource } from "../../reducers/ast";
 
 // this will need to be changed so that addCLientBreakpoint is removed
 
 import type { ThunkArgs, Action } from "../types";
-import type { Breakpoint, SourceLocation, XHRBreakpoint } from "../../types";
+import type { Breakpoint, Location, XHRBreakpoint } from "../../types";
 
 import { recordEvent } from "../../utils/telemetry";
 
 type addBreakpointOptions = {
   condition?: string,
   hidden?: boolean
 };
 
 /**
  * Remove a single breakpoint
  *
  * @memberof actions/breakpoints
  * @static
  */
-export function removeBreakpoint(location: SourceLocation) {
+export function removeBreakpoint(location: Location) {
   return ({ dispatch, getState, client }: ThunkArgs) => {
     const bp = getBreakpoint(getState(), location);
     if (!bp || bp.loading) {
       return;
     }
 
     recordEvent("remove_breakpoint");
 
@@ -79,17 +79,17 @@ export function removeBreakpoint(locatio
 }
 
 /**
  * Disable a single breakpoint
  *
  * @memberof actions/breakpoints
  * @static
  */
-export function disableBreakpoint(location: SourceLocation) {
+export function disableBreakpoint(location: Location) {
   return async ({ dispatch, getState, client }: ThunkArgs) => {
     const bp = getBreakpoint(getState(), location);
 
     if (!bp || bp.loading) {
       return;
     }
 
     await client.removeBreakpoint(bp.generatedLocation);
@@ -215,24 +215,24 @@ export function remapBreakpoints(sourceI
 }
 
 /**
  * Update the condition of a breakpoint.
  *
  * @throws {Error} "not implemented"
  * @memberof actions/breakpoints
  * @static
- * @param {SourceLocation} location
+ * @param {Location} location
  *        @see DebuggerController.Breakpoints.addBreakpoint
  * @param {string} condition
  *        The condition to set on the breakpoint
  * @param {Boolean} $1.disabled Disable value for breakpoint value
  */
 export function setBreakpointCondition(
-  location: SourceLocation,
+  location: Location,
   { condition }: addBreakpointOptions = {}
 ) {
   return async ({ dispatch, getState, client, sourceMaps }: ThunkArgs) => {
     const bp = getBreakpoint(getState(), location);
     if (!bp) {
       return dispatch(addBreakpoint(location, { condition }));
     }
 
--- a/devtools/client/debugger/new/src/actions/breakpoints/syncBreakpoint.js
+++ b/devtools/client/debugger/new/src/actions/breakpoints/syncBreakpoint.js
@@ -13,31 +13,31 @@ import {
 
 import { getGeneratedLocation } from "../../utils/source-maps";
 import { getTextAtPosition } from "../../utils/source";
 import { originalToGeneratedId, isOriginalId } from "devtools-source-map";
 import { getSource } from "../../selectors";
 import type { ThunkArgs, Action } from "../types";
 
 import type {
-  SourceLocation,
+  Location,
   ASTLocation,
   PendingBreakpoint,
   SourceId,
   Breakpoint
 } from "../../types";
 
 type BreakpointSyncData = {
-  previousLocation: SourceLocation,
+  previousLocation: Location,
   breakpoint: ?Breakpoint
 };
 
 async function makeScopedLocation(
   { name, offset }: ASTLocation,
-  location: SourceLocation,
+  location: Location,
   source
 ) {
   const scope = await findScopeByName(source, name);
   // fallback onto the location line, if the scope is not found
   // note: we may at some point want to delete the breakpoint if the scope
   // disappears
   const line = scope ? scope.location.start.line + offset.line : location.line;
   return {
@@ -46,19 +46,19 @@ async function makeScopedLocation(
     sourceUrl: source.url,
     sourceId: source.id
   };
 }
 
 function createSyncData(
   id: SourceId,
   pendingBreakpoint: PendingBreakpoint,
-  location: SourceLocation,
-  generatedLocation: SourceLocation,
-  previousLocation: SourceLocation,
+  location: Location,
+  generatedLocation: Location,
+  previousLocation: Location,
   text: string,
   originalText: string
 ): BreakpointSyncData {
   const overrides = {
     ...pendingBreakpoint,
     generatedLocation,
     id,
     text,
--- a/devtools/client/debugger/new/src/actions/index.js
+++ b/devtools/client/debugger/new/src/actions/index.js
@@ -1,16 +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 <http://mozilla.org/MPL/2.0/>. */
 
 // @flow
 
 import * as breakpoints from "./breakpoints";
 import * as expressions from "./expressions";
+import * as eventListeners from "./event-listeners";
 import * as pause from "./pause";
 import * as navigation from "./navigation";
 import * as ui from "./ui";
 import * as fileSearch from "./file-search";
 import * as ast from "./ast";
 import * as projectTextSearch from "./project-text-search";
 import * as quickOpen from "./quick-open";
 import * as sourceTree from "./source-tree";
@@ -19,16 +20,17 @@ import * as tabs from "./tabs";
 import * as debuggee from "./debuggee";
 import * as toolbox from "./toolbox";
 import * as preview from "./preview";
 
 export default {
   ...navigation,
   ...breakpoints,
   ...expressions,
+  ...eventListeners,
   ...sources,
   ...tabs,
   ...pause,
   ...ui,
   ...fileSearch,
   ...ast,
   ...projectTextSearch,
   ...quickOpen,
--- a/devtools/client/debugger/new/src/actions/moz.build
+++ b/devtools/client/debugger/new/src/actions/moz.build
@@ -9,16 +9,17 @@ DIRS += [
     'pause',
     'sources',
     'utils',
 ]
 
 DebuggerModules(
     'ast.js',
     'debuggee.js',
+    'event-listeners.js',
     'expressions.js',
     'file-search.js',
     'index.js',
     'navigation.js',
     'preview.js',
     'project-text-search.js',
     'quick-open.js',
     'source-tree.js',
--- a/devtools/client/debugger/new/src/actions/preview.js
+++ b/devtools/client/debugger/new/src/actions/preview.js
@@ -17,17 +17,17 @@ import {
   getSelectedFrame,
   getSymbols
 } from "../selectors";
 
 import { getMappedExpression } from "./expressions";
 import { getExtra } from "./pause";
 
 import type { Action, ThunkArgs } from "./types";
-import type { Position } from "../types";
+import type { ColumnPosition } from "../types";
 import type { AstLocation } from "../workers/parser";
 
 function findExpressionMatch(state, codeMirror, tokenPos) {
   const source = getSelectedSource(state);
   if (!source) {
     return;
   }
 
@@ -70,17 +70,17 @@ export function updatePreview(
 
     dispatch(setPreview(expression, location, tokenPos, cursorPos));
   };
 }
 
 export function setPreview(
   expression: string,
   location: AstLocation,
-  tokenPos: Position,
+  tokenPos: ColumnPosition,
   cursorPos: ClientRect
 ) {
   return async ({ dispatch, getState, client, sourceMaps }: ThunkArgs) => {
     await dispatch({
       type: "SET_PREVIEW",
       [PROMISE]: (async function() {
         const source = getSelectedSource(getState());
         if (!source) {
--- a/devtools/client/debugger/new/src/actions/sources/newSources.js
+++ b/devtools/client/debugger/new/src/actions/sources/newSources.js
@@ -120,22 +120,17 @@ function checkSelectedSource(sourceId: s
 
     if (rawPendingUrl === source.url) {
       if (isPrettyURL(pendingUrl)) {
         const prettySource = await dispatch(togglePrettyPrint(source.id));
         return dispatch(checkPendingBreakpoints(prettySource.id));
       }
 
       await dispatch(
-        selectLocation({
-          sourceId: source.id,
-          line:
-            typeof pendingLocation.line === "number" ? pendingLocation.line : 0,
-          column: pendingLocation.column
-        })
+        selectLocation({ ...pendingLocation, sourceId: source.id })
       );
     }
   };
 }
 
 function checkPendingBreakpoints(sourceId: string) {
   return async ({ dispatch, getState }: ThunkArgs) => {
     // source may have been modified by selectLocation
--- a/devtools/client/debugger/new/src/actions/sources/select.js
+++ b/devtools/client/debugger/new/src/actions/sources/select.js
@@ -29,23 +29,20 @@ import {
   getSource,
   getSourceByURL,
   getPrettySource,
   getActiveSearch,
   getSelectedLocation,
   getSelectedSource
 } from "../../selectors";
 
-import type { SourceLocation, PartialPosition, Source } from "../../types";
+import type { Location, Position, Source } from "../../types";
 import type { ThunkArgs } from "../types";
 
-export const setSelectedLocation = (
-  source: Source,
-  location: SourceLocation
-) => ({
+export const setSelectedLocation = (source: Source, location: Location) => ({
   type: "SET_SELECTED_LOCATION",
   source,
   location
 });
 
 export const setPendingSelectedLocation = (url: string, options: Object) => ({
   type: "SET_PENDING_SELECTED_LOCATION",
   url: url,
@@ -62,20 +59,17 @@ export const clearSelectedLocation = () 
  * yet.
  *
  * This exists mostly for external things to interact with the
  * debugger.
  *
  * @memberof actions/sources
  * @static
  */
-export function selectSourceURL(
-  url: string,
-  options: PartialPosition = { line: 1 }
-) {
+export function selectSourceURL(url: string, options: Position = { line: 1 }) {
   return async ({ dispatch, getState, sourceMaps }: ThunkArgs) => {
     const source = getSourceByURL(getState(), url);
     if (!source) {
       return dispatch(setPendingSelectedLocation(url, options));
     }
 
     const sourceId = source.id;
     const location = createLocation({ ...options, sourceId });
@@ -94,17 +88,17 @@ export function selectSource(sourceId: s
   };
 }
 
 /**
  * @memberof actions/sources
  * @static
  */
 export function selectLocation(
-  location: SourceLocation,
+  location: Location,
   { keepContext = true }: Object = {}
 ) {
   return async ({ dispatch, getState, sourceMaps, client }: ThunkArgs) => {
     const currentSource = getSelectedSource(getState());
 
     if (!client) {
       // No connection, do nothing. This happens when the debugger is
       // shut down too fast and it tries to display a default source.
@@ -170,25 +164,25 @@ export function selectLocation(
     }
   };
 }
 
 /**
  * @memberof actions/sources
  * @static
  */
-export function selectSpecificLocation(location: SourceLocation) {
+export function selectSpecificLocation(location: Location) {
   return selectLocation(location, { keepContext: false });
 }
 
 /**
  * @memberof actions/sources
  * @static
  */
-export function jumpToMappedLocation(location: SourceLocation) {
+export function jumpToMappedLocation(location: Location) {
   return async function({ dispatch, getState, client, sourceMaps }: ThunkArgs) {
     if (!client) {
       return;
     }
 
     const pairedLocation = await getMappedLocation(
       getState(),
       sourceMaps,
--- a/devtools/client/debugger/new/src/actions/utils/middleware/promise.js
+++ b/devtools/client/debugger/new/src/actions/utils/middleware/promise.js
@@ -77,29 +77,33 @@ function promiseMiddleware({
     // Create a new action that doesn't have the promise field and has
     // the `seqId` field that represents the sequence id
     action = { ...filterAction(action), seqId };
 
     dispatch({ ...action, status: "start" });
 
     // Return the promise so action creators can still compose if they
     // want to.
-    return Promise.resolve(promiseInst)
-      .finally(() => new Promise(resolve => executeSoon(resolve)))
-      .then(
+    return new Promise((resolve, reject) => {
+      promiseInst.then(
         value => {
-          dispatch({ ...action, status: "done", value: value });
-          return value;
+          executeSoon(() => {
+            dispatch({ ...action, status: "done", value: value });
+            resolve(value);
+          });
         },
         error => {
-          dispatch({
-            ...action,
-            status: "error",
-            error: error.message || error
+          executeSoon(() => {
+            dispatch({
+              ...action,
+              status: "error",
+              error: error.message || error
+            });
+            reject(error);
           });
-          return Promise.reject(error);
         }
       );
+    });
   };
 }
 
 export const PROMISE = "@@dispatch/promise";
 export { promiseMiddleware as promise };
--- a/devtools/client/debugger/new/src/actions/utils/moz.build
+++ b/devtools/client/debugger/new/src/actions/utils/moz.build
@@ -4,9 +4,10 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DIRS += [
     'middleware',
 ]
 
 DebuggerModules(
     'create-store.js',
+    'symbols.js',
 )
--- a/devtools/client/debugger/new/src/client/firefox/commands.js
+++ b/devtools/client/debugger/new/src/client/firefox/commands.js
@@ -4,17 +4,17 @@
 
 // @flow
 
 import type {
   BreakpointId,
   BreakpointResult,
   Frame,
   FrameId,
-  SourceLocation,
+  Location,
   Script,
   Source,
   SourceId,
   Worker
 } from "../../types";
 
 import type {
   TabTarget,
@@ -124,17 +124,17 @@ function breakOnNext(): Promise<*> {
   return threadClient.breakOnNext();
 }
 
 function sourceContents(sourceId: SourceId): Source {
   const sourceClient = threadClient.source({ actor: sourceId });
   return sourceClient.source();
 }
 
-function getBreakpointByLocation(location: SourceLocation) {
+function getBreakpointByLocation(location: Location) {
   const id = makePendingLocationId(location);
   const bpClient = bpClients[id];
 
   if (bpClient) {
     const { actor, url, line, column, condition } = bpClient.location;
     return {
       id: bpClient.actor,
       condition,
@@ -153,17 +153,17 @@ function setXHRBreakpoint(path: string, 
   return threadClient.setXHRBreakpoint(path, method);
 }
 
 function removeXHRBreakpoint(path: string, method: string) {
   return threadClient.removeXHRBreakpoint(path, method);
 }
 
 function setBreakpoint(
-  location: SourceLocation,
+  location: Location,
   condition: boolean,
   noSliding: boolean
 ): Promise<BreakpointResult> {
   const sourceClient = threadClient.source({ actor: location.sourceId });
 
   return sourceClient
     .setBreakpoint({
       line: location.line,
@@ -179,17 +179,17 @@ function setBreakpoint(
       bpClient.location.column = actualLocation.column;
       bpClient.location.url = actualLocation.sourceUrl || "";
 
       return { id, actualLocation };
     });
 }
 
 function removeBreakpoint(
-  generatedLocation: SourceLocation
+  generatedLocation: Location
 ): Promise<void> | ?BreakpointResult {
   try {
     const id = makePendingLocationId(generatedLocation);
     const bpClient = bpClients[id];
     if (!bpClient) {
       console.warn("No breakpoint to delete on server");
       return Promise.resolve();
     }
@@ -197,17 +197,17 @@ function removeBreakpoint(
     return bpClient.remove();
   } catch (_error) {
     console.warn("No breakpoint to delete on server");
   }
 }
 
 function setBreakpointCondition(
   breakpointId: BreakpointId,
-  location: SourceLocation,
+  location: Location,
   condition: boolean,
   noSliding: boolean
 ) {
   const bpClient = bpClients[breakpointId];
   delete bpClients[breakpointId];
 
   return bpClient
     .setCondition(threadClient, condition, noSliding)
--- a/devtools/client/debugger/new/src/client/firefox/create.js
+++ b/devtools/client/debugger/new/src/client/firefox/create.js
@@ -1,16 +1,16 @@
 /* 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
 // This module converts Firefox specific types to the generic types
 
-import type { Frame, Source, SourceLocation } from "../../types";
+import type { Frame, Source, Location } from "../../types";
 import type {
   PausedPacket,
   FramesResponse,
   FramePacket,
   SourcePayload
 } from "./types";
 
 export function createFrame(frame: FramePacket): ?Frame {
@@ -73,19 +73,19 @@ export function createPause(
   };
 }
 
 // Firefox only returns `actualLocation` if it actually changed,
 // but we want it always to exist. Format `actualLocation` if it
 // exists, otherwise use `location`.
 
 export function createBreakpointLocation(
-  location: SourceLocation,
+  location: Location,
   actualLocation?: Object
-): SourceLocation {
+): Location {
   if (!actualLocation) {
     return location;
   }
 
   return {
     sourceId: actualLocation.source.actor,
     sourceUrl: actualLocation.source.url,
     line: actualLocation.line,
--- a/devtools/client/debugger/new/src/client/firefox/events.js
+++ b/devtools/client/debugger/new/src/client/firefox/events.js
@@ -9,16 +9,17 @@ import type {
   ResumedPacket,
   PausedPacket,
   ThreadClient,
   Actions
 } from "./types";
 
 import { createPause, createSource } from "./create";
 import sourceQueue from "../../utils/source-queue";
+import { features } from "../../utils/prefs";
 
 const CALL_STACK_PAGE_SIZE = 1000;
 
 type Dependencies = {
   threadClient: ThreadClient,
   actions: Actions,
   supportsWasm: boolean
 };
@@ -94,16 +95,20 @@ function resumed(_: "resumed", packet: R
     return;
   }
 
   actions.resumed(packet);
 }
 
 function newSource(_: "newSource", { source }: SourcePacket) {
   sourceQueue.queue(source);
+
+  if (features.eventListeners) {
+    actions.fetchEventListeners();
+  }
 }
 
 function workerListChanged() {
   actions.updateWorkers();
 }
 
 const clientEvents = {
   paused,
--- a/devtools/client/debugger/new/src/components/Editor/ColumnBreakpoint.js
+++ b/devtools/client/debugger/new/src/components/Editor/ColumnBreakpoint.js
@@ -1,18 +1,16 @@
 /* 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, { PureComponent } from "react";
-import ReactDOM from "react-dom";
+import { PureComponent } from "react";
 import classnames from "classnames";
 import { getDocument } from "../../utils/editor";
-import Svg from "../shared/Svg";
 
 // eslint-disable-next-line max-len
 import type { ColumnBreakpoint as ColumnBreakpointType } from "../../selectors/visibleColumnBreakpoints";
 
 type Bookmark = {
   clear: Function
 };
 
@@ -21,21 +19,21 @@ type Props = {
   editor: Object,
   source: Object,
   enabled: boolean,
   toggleBreakpoint: (number, number) => void,
   columnBreakpoint: ColumnBreakpointType
 };
 
 const breakpointImg = document.createElement("div");
-ReactDOM.render(<Svg name={"column-marker"} />, breakpointImg);
 function makeBookmark(isActive, { onClick }) {
   const bp = breakpointImg.cloneNode(true);
-  const className = isActive ? "active" : "disabled";
-  bp.className = classnames("call-site", className);
+  bp.className = classnames("call-site", {
+    active: isActive
+  });
   bp.onclick = onClick;
   return bp;
 }
 
 export default class CallSite extends PureComponent<Props> {
   addCallSite: Function;
   bookmark: ?Bookmark;
 
--- a/devtools/client/debugger/new/src/components/Editor/Footer.js
+++ b/devtools/client/debugger/new/src/components/Editor/Footer.js
@@ -25,54 +25,28 @@ import { getGeneratedSource } from "../.
 import { shouldShowFooter, shouldShowPrettyPrint } from "../../utils/editor";
 
 import { PaneToggleButton } from "../shared/Button";
 
 import type { Source } from "../../types";
 
 import "./Footer.css";
 
-type CursorPosition = {
-  line: number,
-  column: number
-};
-
 type Props = {
   selectedSource: Source,
   mappedSource: Source,
   endPanelCollapsed: boolean,
-  editor: Object,
   horizontal: boolean,
   togglePrettyPrint: string => void,
   toggleBlackBox: Object => void,
   jumpToMappedLocation: (Source: any) => void,
   togglePaneCollapse: () => void
 };
 
-type State = {
-  cursorPosition: CursorPosition
-};
-
-class SourceFooter extends PureComponent<Props, State> {
-  constructor() {
-    super();
-
-    this.state = { cursorPosition: { line: 1, column: 1 } };
-  }
-
-  componentDidMount() {
-    const { editor } = this.props;
-    editor.codeMirror.on("cursorActivity", this.onCursorChange);
-  }
-
-  componentWillUnmount() {
-    const { editor } = this.props;
-    editor.codeMirror.off("cursorActivity", this.onCursorChange);
-  }
-
+class SourceFooter extends PureComponent<Props> {
   prettyPrintButton() {
     const { selectedSource, togglePrettyPrint } = this.props;
 
     if (isLoading(selectedSource) && selectedSource.isPrettyPrinted) {
       return (
         <div className="loader">
           <Svg name="loader" />
         </div>
@@ -195,43 +169,26 @@ class SourceFooter extends PureComponent
         onClick={() => jumpToMappedLocation(mappedSourceLocation)}
         title={tooltip}
       >
         <span>{title}</span>
       </button>
     );
   }
 
-  onCursorChange = event => {
-    const { line, ch } = event.doc.getCursor();
-    this.setState({ cursorPosition: { line, column: ch } });
-  };
-
-  renderCursorPosition() {
-    const { cursorPosition } = this.state;
-
-    const text = L10N.getFormatStr(
-      "sourceFooter.currentCursorPosition",
-      cursorPosition.line + 1,
-      cursorPosition.column + 1
-    );
-    return <span className="cursor-position">{text}</span>;
-  }
-
   render() {
     const { selectedSource, horizontal } = this.props;
 
     if (!shouldShowFooter(selectedSource, horizontal)) {
       return null;
     }
 
     return (
       <div className="source-footer">
         {this.renderCommands()}
-        {this.renderCursorPosition()}
         {this.renderSourceSummary()}
         {this.renderToggleButton()}
       </div>
     );
   }
 }
 
 const mapStateToProps = state => {
--- a/devtools/client/debugger/new/src/components/Editor/HighlightLine.js
+++ b/devtools/client/debugger/new/src/components/Editor/HighlightLine.js
@@ -11,27 +11,27 @@ import { isLoaded } from "../../utils/so
 import { connect } from "react-redux";
 import {
   getVisibleSelectedFrame,
   getSelectedLocation,
   getSelectedSource,
   getPauseCommand
 } from "../../selectors";
 
-import type { Frame, SourceLocation, Source } from "../../types";
+import type { Frame, Location, Source } from "../../types";
 import type { Command } from "../../reducers/types";
 
 type Props = {
   pauseCommand: Command,
   selectedFrame: Frame,
-  selectedLocation: SourceLocation,
+  selectedLocation: Location,
   selectedSource: Source
 };
 
-function isDebugLine(selectedFrame: Frame, selectedLocation: SourceLocation) {
+function isDebugLine(selectedFrame: Frame, selectedLocation: Location) {
   if (!selectedFrame) {
     return;
   }
 
   return (
     selectedFrame.location.sourceId == selectedLocation.sourceId &&
     selectedFrame.location.line == selectedLocation.line
   );
@@ -49,20 +49,17 @@ export class HighlightLine extends Compo
   isStepping: boolean = false;
   previousEditorLine: ?number = null;
 
   shouldComponentUpdate(nextProps: Props) {
     const { selectedLocation, selectedSource } = nextProps;
     return this.shouldSetHighlightLine(selectedLocation, selectedSource);
   }
 
-  shouldSetHighlightLine(
-    selectedLocation: SourceLocation,
-    selectedSource: Source
-  ) {
+  shouldSetHighlightLine(selectedLocation: Location, selectedSource: Source) {
     const { sourceId, line } = selectedLocation;
     const editorLine = toEditorLine(sourceId, line);
 
     if (!isDocumentReady(selectedSource, selectedLocation)) {
       return false;
     }
 
     if (this.isStepping && editorLine === this.previousEditorLine) {
@@ -88,17 +85,17 @@ export class HighlightLine extends Compo
       prevProps.selectedLocation,
       prevProps.selectedSource
     );
     this.setHighlightLine(selectedLocation, selectedFrame, selectedSource);
     endOperation();
   }
 
   setHighlightLine(
-    selectedLocation: SourceLocation,
+    selectedLocation: Location,
     selectedFrame: Frame,
     selectedSource: Source
   ) {
     const { sourceId, line } = selectedLocation;
     if (!this.shouldSetHighlightLine(selectedLocation, selectedSource)) {
       return;
     }
     this.isStepping = false;
@@ -108,17 +105,17 @@ export class HighlightLine extends Compo
     if (!line || isDebugLine(selectedFrame, selectedLocation)) {
       return;
     }
 
     const doc = getDocument(sourceId);
     doc.addLineClass(editorLine, "line", "highlight-line");
   }
 
-  clearHighlightLine(selectedLocation: SourceLocation, selectedSource: Source) {
+  clearHighlightLine(selectedLocation: Location, selectedSource: Source) {
     if (!isDocumentReady(selectedSource, selectedLocation)) {
       return;
     }
 
     const { line, sourceId } = selectedLocation;
     const editorLine = toEditorLine(sourceId, line);
     const doc = getDocument(sourceId);
     doc.removeLineClass(editorLine, "line", "highlight-line");
--- a/devtools/client/debugger/new/src/components/Editor/index.js
+++ b/devtools/client/debugger/new/src/components/Editor/index.js
@@ -62,25 +62,25 @@ import {
 
 import { resizeToggleButton, resizeBreakpointGutter } from "../../utils/ui";
 
 import "./Editor.css";
 import "./Highlight.css";
 
 import type SourceEditor from "../../utils/editor/source-editor";
 import type { SymbolDeclarations } from "../../workers/parser";
-import type { SourceLocation, Source } from "../../types";
+import type { Location, Source } from "../../types";
 
 const cssVars = {
   searchbarHeight: "var(--editor-searchbar-height)",
   footerHeight: "var(--editor-footer-height)"
 };
 
 export type Props = {
-  selectedLocation: ?SourceLocation,
+  selectedLocation: ?Location,
   selectedSource: ?Source,
   searchOn: boolean,
   horizontal: boolean,
   startPanelSize: number,
   endPanelSize: number,
   conditionalPanelLine: number,
   symbols: SymbolDeclarations,
 
@@ -544,17 +544,17 @@ class Editor extends PureComponent<Props
 
     return (
       <div>
         <DebugLine editor={editor} />
         <HighlightLine />
         <EmptyLines editor={editor} />
         <Breakpoints editor={editor} />
         <Preview editor={editor} editorRef={this.$editorWrapper} />;
-        <Footer editor={editor} horizontal={horizontal} />
+        <Footer horizontal={horizontal} />
         <HighlightLines editor={editor} />
         <EditorMenu editor={editor} />
         <GutterMenu editor={editor} />
         <ConditionalPanel editor={editor} />
         {features.columnBreakpoints ? (
           <ColumnBreakpoints editor={editor} />
         ) : null}
       </div>
--- a/devtools/client/debugger/new/src/components/ProjectSearch.js
+++ b/devtools/client/debugger/new/src/components/ProjectSearch.js
@@ -23,17 +23,17 @@ import {
   getTextSearchQuery
 } from "../selectors";
 
 import Svg from "./shared/Svg";
 import ManagedTree from "./shared/ManagedTree";
 import SearchInput from "./shared/SearchInput";
 
 import type { List } from "immutable";
-import type { SourceLocation } from "../types";
+import type { Location } from "../types";
 import type { ActiveSearchType } from "../reducers/types";
 import type { StatusType } from "../reducers/project-text-search";
 type Editor = ?Object;
 
 import "./ProjectSearch.css";
 
 export type Match = {
   type: "MATCH",
@@ -63,17 +63,17 @@ type Props = {
   sources: Object,
   query: string,
   results: List<Result>,
   status: StatusType,
   activeSearch: ActiveSearchType,
   closeProjectSearch: () => void,
   searchSources: (query: string) => void,
   clearSearch: () => void,
-  selectSpecificLocation: (location: SourceLocation, tabIndex?: string) => void,
+  selectSpecificLocation: (location: Location, tabIndex?: string) => void,
   setActiveSearch: (activeSearch?: ActiveSearchType) => void,
   doSearchForHighlight: (
     query: string,
     editor: Editor,
     line: number,
     column: number
   ) => void
 };
@@ -145,21 +145,17 @@ export class ProjectSearch extends Compo
     }
 
     return setActiveSearch("project");
   };
 
   isProjectSearchEnabled = () => this.props.activeSearch === "project";
 
   selectMatchItem = (matchItem: Match) => {
-    this.props.selectSpecificLocation({
-      sourceId: matchItem.sourceId,
-      line: matchItem.line,
-      column: matchItem.column
-    });
+    this.props.selectSpecificLocation({ ...matchItem });
     this.props.doSearchForHighlight(
       this.state.inputValue,
       getEditor(),
       matchItem.line,
       matchItem.column
     );
   };
 
--- a/devtools/client/debugger/new/src/components/QuickOpenModal.js
+++ b/devtools/client/debugger/new/src/components/QuickOpenModal.js
@@ -30,33 +30,32 @@ import Modal from "./shared/Modal";
 import SearchInput from "./shared/SearchInput";
 import ResultList from "./shared/ResultList";
 
 import type {
   FormattedSymbolDeclarations,
   QuickOpenResult
 } from "../utils/quick-open";
 
-import type { SourceLocation, Source } from "../types";
+import type { Location, Source } from "../types";
 import type { QuickOpenType } from "../reducers/quick-open";
-import type { Tab } from "../reducers/tabs";
 
 import "./QuickOpenModal.css";
 
 type Props = {
   enabled: boolean,
   sources: Array<Object>,
   selectedSource?: Source,
   query: string,
   searchType: QuickOpenType,
   symbols: FormattedSymbolDeclarations,
   symbolsLoading: boolean,
-  tabs: Tab[],
+  tabs: string[],
   shortcutsModalEnabled: boolean,
-  selectSpecificLocation: SourceLocation => void,
+  selectSpecificLocation: Location => void,
   setQuickOpenQuery: (query: string) => void,
   highlightLineRange: ({ start: number, end: number }) => void,
   closeQuickOpen: () => void,
   toggleShortcutsModal: () => void
 };
 
 type State = {
   results: ?Array<QuickOpenResult>,
@@ -121,22 +120,22 @@ export class QuickOpenModal extends Comp
     const { sources } = this.props;
     const results =
       query == "" ? sources : filter(sources, this.dropGoto(query));
     return this.setState({ results });
   };
 
   searchSymbols = (query: string) => {
     const {
-      symbols: { functions, identifiers }
+      symbols: { functions, variables }
     } = this.props;
 
     let results = functions;
     if (this.isVariableQuery()) {
-      results = identifiers;
+      results = variables;
     } else {
       results = results.filter(result => result.title !== "anonymous");
     }
 
     if (query === "@" || query === "#") {
       return this.setState({ results });
     }
 
@@ -150,20 +149,18 @@ export class QuickOpenModal extends Comp
     } else {
       this.setState({ results: filter(results, query.slice(1)) });
     }
   };
 
   showTopSources = () => {
     const { tabs, sources } = this.props;
     if (tabs.length > 0) {
-      const tabUrls = tabs.map((tab: Tab) => tab.url);
-
       this.setState({
-        results: sources.filter(source => tabUrls.includes(source.url))
+        results: sources.filter(source => tabs.includes(source.url))
       });
     } else {
       this.setState({ results: sources.slice(0, 100) });
     }
   };
 
   updateResults = (query: string) => {
     if (this.isGotoQuery()) {
--- a/devtools/client/debugger/new/src/components/SecondaryPanes/Breakpoints/Breakpoint.js
+++ b/devtools/client/debugger/new/src/components/SecondaryPanes/Breakpoints/Breakpoint.js
@@ -20,22 +20,22 @@ import { features } from "../../../utils
 import { getEditor } from "../../../utils/editor";
 
 import type { FormattedBreakpoint } from "../../../selectors/breakpointSources";
 
 import type {
   Breakpoint as BreakpointType,
   Frame,
   Source,
-  SourceLocation
+  Location
 } from "../../../types";
 
 type FormattedFrame = {
   ...Frame,
-  selectedLocation: SourceLocation
+  selectedLocation: Location
 };
 
 import {
   getBreakpointsList,
   getSelectedFrame,
   getSelectedSource
 } from "../../../selectors";
 
@@ -47,17 +47,16 @@ type Props = {
   enableBreakpoint: typeof actions.enableBreakpoint,
   removeBreakpoint: typeof actions.removeBreakpoint,
   removeBreakpoints: typeof actions.removeBreakpoints,
   removeAllBreakpoints: typeof actions.removeAllBreakpoints,
   disableBreakpoint: typeof actions.disableBreakpoint,
   setBreakpointCondition: typeof actions.setBreakpointCondition,
   toggleAllBreakpoints: typeof actions.toggleAllBreakpoints,
   toggleBreakpoints: typeof actions.toggleBreakpoints,
-  toggleDisabledBreakpoint: typeof actions.toggleDisabledBreakpoint,
   openConditionalPanel: typeof actions.openConditionalPanel,
   selectSpecificLocation: typeof actions.selectSpecificLocation
 };
 
 class Breakpoint extends PureComponent<Props> {
   onContextMenu = e => {
     showContextMenu({ ...this.props, contextMenuEvent: e });
   };
@@ -201,12 +200,11 @@ export default connect(
     removeBreakpoints: actions.removeBreakpoints,
     removeAllBreakpoints: actions.removeAllBreakpoints,
     disableBreakpoint: actions.disableBreakpoint,
     selectSpecificLocation: actions.selectSpecificLocation,
     selectLocation: actions.selectLocation,
     setBreakpointCondition: actions.setBreakpointCondition,
     toggleAllBreakpoints: actions.toggleAllBreakpoints,
     toggleBreakpoints: actions.toggleBreakpoints,
-    toggleDisabledBreakpoint: actions.toggleDisabledBreakpoint,
     openConditionalPanel: actions.openConditionalPanel
   }
 )(Breakpoint);
--- a/devtools/client/debugger/new/src/components/SecondaryPanes/index.js
+++ b/devtools/client/debugger/new/src/components/SecondaryPanes/index.js
@@ -24,16 +24,17 @@ import {
 
 import Svg from "../shared/Svg";
 import { prefs, features } from "../../utils/prefs";
 
 import Breakpoints from "./Breakpoints";
 import Expressions from "./Expressions";
 import SplitBox from "devtools-splitter";
 import Frames from "./Frames";
+import EventListeners from "./EventListeners";
 import Workers from "./Workers";
 import Accordion from "../shared/Accordion";
 import CommandBar from "./CommandBar";
 import UtilsBar from "./UtilsBar";
 import FrameworkComponent from "./FrameworkComponent";
 import XHRBreakpoints from "./XHRBreakpoints";
 
 import Scopes from "./Scopes";
@@ -342,16 +343,24 @@ class SecondaryPanes extends Component<P
         items.push(this.getScopeItem());
       }
     }
 
     if (features.xhrBreakpoints) {
       items.push(this.getXHRItem());
     }
 
+    if (features.eventListeners) {
+      items.push({
+        header: L10N.getStr("eventListenersHeader"),
+        className: "event-listeners-pane",
+        component: <EventListeners />
+      });
+    }
+
     return items.filter(item => item);
   }
 
   renderHorizontalLayout() {
     return <Accordion items={this.getItems()} />;
   }
 
   getEndItems() {
--- a/devtools/client/debugger/new/src/components/SecondaryPanes/moz.build
+++ b/devtools/client/debugger/new/src/components/SecondaryPanes/moz.build
@@ -5,16 +5,17 @@
 
 DIRS += [
     'Breakpoints',
     'Frames',
 ]
 
 DebuggerModules(
     'CommandBar.js',
+    'EventListeners.js',
     'Expressions.js',
     'FrameworkComponent.js',
     'index.js',
     'Scopes.js',
     'UtilsBar.js',
     'Workers.js',
     'XHRBreakpoints.js',
 )
--- a/devtools/client/debugger/new/src/reducers/ast.js
+++ b/devtools/client/debugger/new/src/reducers/ast.js
@@ -16,17 +16,17 @@ import { findEmptyLines } from "../utils
 import type {
   AstLocation,
   SymbolDeclarations,
   PausePoints,
   PausePoint
 } from "../workers/parser";
 
 import type { Map } from "immutable";
-import type { SourceLocation, Source } from "../types";
+import type { Location, Source } from "../types";
 import type { Action, DonePromiseAction } from "../actions/types";
 import type { Record } from "../utils/makeRecord";
 
 type EmptyLinesType = number[];
 
 export type Symbols = SymbolDeclarations | {| loading: true |};
 export type SymbolsMap = Map<string, Symbols>;
 export type EmptyLinesMap = Map<string, EmptyLinesType>;
@@ -204,17 +204,17 @@ export function getPausePoints(
   state: OuterState,
   sourceId: string
 ): ?PausePoints {
   return state.ast.pausePoints.get(sourceId);
 }
 
 export function getPausePoint(
   state: OuterState,
-  location: ?SourceLocation
+  location: ?Location
 ): ?PausePoint {
   if (!location) {
     return;
   }
 
   const { column, line, sourceId } = location;
   const pausePoints = getPausePoints(state, sourceId);
   if (!pausePoints) {
--- a/devtools/client/debugger/new/src/reducers/breakpoints.js
+++ b/devtools/client/debugger/new/src/reducers/breakpoints.js
@@ -9,17 +9,17 @@
  * @module reducers/breakpoints
  */
 
 import * as I from "immutable";
 
 import { isGeneratedId } from "devtools-source-map";
 import { makeLocationId } from "../utils/breakpoint";
 
-import type { XHRBreakpoint, Breakpoint, SourceLocation } from "../types";
+import type { XHRBreakpoint, Breakpoint, Location } from "../types";
 import type { Action, DonePromiseAction } from "../actions/types";
 
 export type BreakpointsMap = { [string]: Breakpoint };
 export type XHRBreakpointsList = I.List<XHRBreakpoint>;
 
 export type BreakpointsState = {
   breakpoints: BreakpointsMap,
   xhrBreakpoints: XHRBreakpointsList
@@ -265,17 +265,17 @@ export function getBreakpointsList(state
 }
 
 export function getBreakpointCount(state: OuterState): number {
   return getBreakpointsList(state).length;
 }
 
 export function getBreakpoint(
   state: OuterState,
-  location: SourceLocation
+  location: Location
 ): ?Breakpoint {
   const breakpoints = getBreakpointsMap(state);
   return breakpoints[makeLocationId(location)];
 }
 
 export function getBreakpointsDisabled(state: OuterState): boolean {
   const breakpoints = getBreakpointsList(state);
   return breakpoints.every(breakpoint => breakpoint.disabled);
@@ -317,19 +317,17 @@ export function getBreakpointForLine(
   return breakpoints.find(breakpoint => breakpoint.location.line === line);
 }
 
 export function getHiddenBreakpoint(state: OuterState): ?Breakpoint {
   const breakpoints = getBreakpointsList(state);
   return breakpoints.find(bp => bp.hidden);
 }
 
-export function getHiddenBreakpointLocation(
-  state: OuterState
-): ?SourceLocation {
+export function getHiddenBreakpointLocation(state: OuterState): ?Location {
   const hiddenBreakpoint = getHiddenBreakpoint(state);
   if (!hiddenBreakpoint) {
     return null;
   }
   return hiddenBreakpoint.location;
 }
 
 export default update;
--- a/devtools/client/debugger/new/src/reducers/index.js
+++ b/devtools/client/debugger/new/src/reducers/index.js
@@ -3,16 +3,17 @@
  * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
 /**
  * Reducer index
  * @module reducers/index
  */
 
 import expressions from "./expressions";
+import eventListeners from "./event-listeners";
 import sources from "./sources";
 import tabs from "./tabs";
 import breakpoints from "./breakpoints";
 import pendingBreakpoints from "./pending-breakpoints";
 import asyncRequests from "./async-requests";
 import pause from "./pause";
 import ui from "./ui";
 import fileSearch from "./file-search";
@@ -20,16 +21,17 @@ import ast from "./ast";
 import projectTextSearch from "./project-text-search";
 import quickOpen from "./quick-open";
 import sourceTree from "./source-tree";
 import debuggee from "./debuggee";
 import { objectInspector } from "devtools-reps";
 
 export default {
   expressions,
+  eventListeners,
   sources,
   tabs,
   breakpoints,
   pendingBreakpoints,
   asyncRequests,
   pause,
   ui,
   fileSearch,
--- a/devtools/client/debugger/new/src/reducers/moz.build
+++ b/devtools/client/debugger/new/src/reducers/moz.build
@@ -7,16 +7,17 @@ DIRS += [
 
 ]
 
 DebuggerModules(
     'ast.js',
     'async-requests.js',
     'breakpoints.js',
     'debuggee.js',
+    'event-listeners.js',
     'expressions.js',
     'file-search.js',
     'index.js',
     'pause.js',
     'pending-breakpoints.js',
     'project-text-search.js',
     'quick-open.js',
     'source-tree.js',
--- a/devtools/client/debugger/new/src/reducers/sources.js
+++ b/devtools/client/debugger/new/src/reducers/sources.js
@@ -15,31 +15,31 @@ import {
   underRoot,
   getRelativeUrl,
   isGenerated,
   isOriginal as isOriginalSource
 } from "../utils/source";
 import { originalToGeneratedId } from "devtools-source-map";
 import { prefs } from "../utils/prefs";
 
-import type { Source, SourceId, SourceLocation } from "../types";
+import type { Source, SourceId, Location } from "../types";
 import type { PendingSelectedLocation } from "./types";
 import type { Action, DonePromiseAction } from "../actions/types";
 import type { LoadSourceAction } from "../actions/types/SourceAction";
 
 export type SourcesMap = { [string]: Source };
 
 type UrlsMap = { [string]: SourceId[] };
 
 export type SourcesState = {
   sources: SourcesMap,
   urls: UrlsMap,
   relativeSources: SourcesMap,
   pendingSelectedLocation?: PendingSelectedLocation,
-  selectedLocation: ?SourceLocation,
+  selectedLocation: ?Location,
   projectDirectoryRoot: string
 };
 
 export function initialSourcesState(): SourcesState {
   return {
     sources: {},
     urls: {},
     relativeSources: {},
@@ -478,17 +478,17 @@ export const getSourceCount = createSele
 export const getSelectedLocation = createSelector(
   getSourcesState,
   sources => sources.selectedLocation
 );
 
 export const getSelectedSource = createSelector(
   getSelectedLocation,
   getSources,
-  (selectedLocation: ?SourceLocation, sources: SourcesMap): ?Source => {
+  (selectedLocation: ?Location, sources: SourcesMap): ?Source => {
     if (!selectedLocation) {
       return;
     }
 
     return sources[selectedLocation.sourceId];
   }
 );
 
--- a/devtools/client/debugger/new/src/reducers/tabs.js
+++ b/devtools/client/debugger/new/src/reducers/tabs.js
@@ -21,17 +21,17 @@ import {
   getSpecificSourceByURL,
   getSpecificSourceByUrlInSources
 } from "./sources";
 
 import type { Action } from "../actions/types";
 import type { SourcesState } from "./sources";
 import type { Source } from "../types";
 
-export type Tab = {
+type Tab = {
   url: string,
   framework?: string | null,
   isOriginal: boolean,
   sourceId?: string
 };
 export type TabList = Tab[];
 
 function isSimilarTab(tab: Tab, url: string, isOriginal: boolean) {
--- a/devtools/client/debugger/new/src/reducers/ui.js
+++ b/devtools/client/debugger/new/src/reducers/ui.js
@@ -7,28 +7,28 @@
 /**
  * UI reducer
  * @module reducers/ui
  */
 
 import makeRecord from "../utils/makeRecord";
 import { prefs } from "../utils/prefs";
 
-import type { Source, PartialRange } from "../types";
+import type { Source, Range } from "../types";
 
 import type { Action, panelPositionType } from "../actions/types";
 import type { Record } from "../utils/makeRecord";
 
 export type ActiveSearchType = "project" | "file";
 
 export type OrientationType = "horizontal" | "vertical";
 
 export type SelectedPrimaryPaneTabType = "sources" | "outline";
 
-type Viewport = PartialRange;
+type Viewport = Range;
 
 export type UIState = {
   selectedPrimaryPaneTab: SelectedPrimaryPaneTabType,
   activeSearch: ?ActiveSearchType,
   contextMenu: any,
   shownSource: ?Source,
   startPanelCollapsed: boolean,
   endPanelCollapsed: boolean,
--- a/devtools/client/debugger/new/src/selectors/breakpointSources.js
+++ b/devtools/client/debugger/new/src/selectors/breakpointSources.js
@@ -9,35 +9,30 @@ import { createSelector } from "reselect
 import {
   getSources,
   getBreakpointsList,
   getSelectedSource
 } from "../selectors";
 import { isGenerated, getFilename } from "../utils/source";
 import { getSelectedLocation } from "../utils/source-maps";
 
-import type {
-  Source,
-  Breakpoint,
-  BreakpointId,
-  SourceLocation
-} from "../types";
+import type { Source, Breakpoint, BreakpointId, Location } from "../types";
 import type { SourcesMap } from "../reducers/types";
 
 export type BreakpointSources = Array<{
   source: Source,
   breakpoints: FormattedBreakpoint[]
 }>;
 
 export type FormattedBreakpoint = {|
   id: BreakpointId,
   condition: ?string,
   disabled: boolean,
   text: string,
-  selectedLocation: SourceLocation
+  selectedLocation: Location
 |};
 
 function formatBreakpoint(
   breakpoint: Breakpoint,
   selectedSource: Source
 ): FormattedBreakpoint {
   const { id, condition, disabled } = breakpoint;
 
--- a/devtools/client/debugger/new/src/selectors/index.js
+++ b/devtools/client/debugger/new/src/selectors/index.js
@@ -12,16 +12,17 @@ export * from "../reducers/debuggee";
 export * from "../reducers/breakpoints";
 export * from "../reducers/pending-breakpoints";
 export * from "../reducers/ui";
 export * from "../reducers/file-search";
 export * from "../reducers/ast";
 export * from "../reducers/project-text-search";
 export * from "../reducers/source-tree";
 
+export { getEventListeners } from "../reducers/event-listeners";
 export {
   getQuickOpenEnabled,
   getQuickOpenQuery,
   getQuickOpenType
 } from "../reducers/quick-open";
 
 export {
   getBreakpointAtLocation,
--- a/devtools/client/debugger/new/src/selectors/visibleColumnBreakpoints.js
+++ b/devtools/client/debugger/new/src/selectors/visibleColumnBreakpoints.js
@@ -1,24 +1,23 @@
 /* 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/>. */
 
-import { groupBy, hasIn, sortedUniqBy } from "lodash";
+import { groupBy, hasIn } from "lodash";
 import { createSelector } from "reselect";
 
 import { getViewport } from "../selectors";
 import { getVisibleBreakpoints } from "./visibleBreakpoints";
 import { getVisiblePausePoints } from "./visiblePausePoints";
-import { makeLocationId } from "../utils/breakpoint";
 
-import type { SourceLocation } from "../types";
+import type { Location } from "../types";
 
 export type ColumnBreakpoint = {|
-  +location: SourceLocation,
+  +location: Location,
   +enabled: boolean
 |};
 
 function contains(location, range) {
   return (
     location.line >= range.start.line &&
     location.line <= range.end.line &&
     location.column >= range.start.column &&
@@ -35,29 +34,16 @@ function groupBreakpoints(breakpoints) {
   return map;
 }
 
 function isEnabled(location, breakpointMap) {
   const { line, column } = location;
   return hasIn(breakpointMap, [line, column]);
 }
 
-function getLineCount(columnBreakpoints) {
-  const lineCount = {};
-  columnBreakpoints.forEach(({ location: { line } }) => {
-    if (!lineCount[line]) {
-      lineCount[line] = 0;
-    }
-
-    lineCount[line] = lineCount[line] + 1;
-  });
-
-  return lineCount;
-}
-
 export function formatColumnBreakpoints(columnBreakpoints) {
   console.log(
     "Column Breakpoints\n\n",
     columnBreakpoints
       .map(
         ({ location, enabled }) =>
           `(${location.line}, ${location.column}) ${enabled}`
       )
@@ -66,45 +52,20 @@ export function formatColumnBreakpoints(
 }
 
 export function getColumnBreakpoints(pausePoints, breakpoints, viewport) {
   if (!pausePoints) {
     return [];
   }
 
   const breakpointMap = groupBreakpoints(breakpoints);
-
-  // We only want to show a column breakpoint if several conditions are matched
-  // 1. it is a "break" point and not a "step" point
-  // 2. there is a breakpoint on that line
-  // 3. the breakpoint is in the current viewport
-  // 4. it is the first breakpoint to appear at that generated location
-  // 5. there is atleast one other breakpoint on that line
-
-  let columnBreakpoints = pausePoints.filter(
-    ({ types, location }) =>
-      // 1. check that the pause point is a "break" point
-      types.break &&
-      // 2. check that there is a registered breakpoint on the line
-      breakpointMap[location.line] &&
-      // 3. check that the breakpoint is visible
-      viewport &&
-      contains(location, viewport)
-  );
-
-  // 4. Only show one column breakpoint per generated location
-  columnBreakpoints = sortedUniqBy(columnBreakpoints, ({ generatedLocation }) =>
-    makeLocationId(generatedLocation)
-  );
-
-  // 5. Check that there is atleast one other possible breakpoint on the line
-  const lineCount = getLineCount(columnBreakpoints);
-  columnBreakpoints = columnBreakpoints.filter(
-    ({ location: { line } }) => lineCount[line] > 1
-  );
+  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(
--- a/devtools/client/debugger/new/src/selectors/visibleSelectedFrame.js
+++ b/devtools/client/debugger/new/src/selectors/visibleSelectedFrame.js
@@ -4,19 +4,19 @@
 
 // @flow
 
 import { getSelectedLocation } from "../reducers/sources";
 import { getSelectedFrame } from "../reducers/pause";
 import { isOriginalId } from "devtools-source-map";
 import { createSelector } from "reselect";
 
-import type { Frame, SourceLocation } from "../types";
+import type { Frame, Location } from "../types";
 
-function getLocation(frame: Frame, location?: SourceLocation) {
+function getLocation(frame: Frame, location?: Location) {
   if (!location) {
     return frame.location;
   }
 
   return !isOriginalId(location.sourceId)
     ? frame.generatedLocation || frame.location
     : frame.location;
 }
--- a/devtools/client/debugger/new/src/utils/ast.js
+++ b/devtools/client/debugger/new/src/utils/ast.js
@@ -2,28 +2,31 @@
  * 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 { xor, range } from "lodash";
 import { convertToList } from "./pause/pausePoints";
 
-import type { SourceLocation, Position } from "../types";
+import type { Location, ColumnPosition } from "../types";
 import type { Symbols } from "../reducers/ast";
 
 import type {
   AstPosition,
   AstLocation,
   PausePoints,
   FunctionDeclaration,
   ClassDeclaration
 } from "../workers/parser";
 
-export function findBestMatchExpression(symbols: Symbols, tokenPos: Position) {
+export function findBestMatchExpression(
+  symbols: Symbols,
+  tokenPos: ColumnPosition
+) {
   if (symbols.loading) {
     return null;
   }
 
   const { line, column } = tokenPos;
   const { memberExpressions, identifiers, literals } = symbols;
   const members = memberExpressions.filter(({ computed }) => !computed);
 
@@ -67,17 +70,17 @@ export function containsPosition(a: AstL
     a.start.line < b.line ||
     (a.start.line === b.line && a.start.column <= b.column);
   const endsAfter =
     a.end.line > b.line || (a.end.line === b.line && a.end.column >= b.column);
 
   return startsBefore && endsAfter;
 }
 
-function findClosestofSymbol(declarations: any[], location: SourceLocation) {
+function findClosestofSymbol(declarations: any[], location: Location) {
   if (!declarations) {
     return null;
   }
 
   return declarations.reduce((found, currNode) => {
     if (
       currNode.name === "anonymous" ||
       !containsPosition(currNode.location, {
@@ -103,27 +106,27 @@ function findClosestofSymbol(declaration
     }
 
     return currNode;
   }, null);
 }
 
 export function findClosestFunction(
   symbols: ?Symbols,
-  location: SourceLocation
+  location: Location
 ): FunctionDeclaration | null {
   if (!symbols || symbols.loading) {
     return null;
   }
 
   return findClosestofSymbol(symbols.functions, location);
 }
 
 export function findClosestClass(
   symbols: Symbols,
-  location: SourceLocation
+  location: Location
 ): ClassDeclaration | null {
   if (!symbols || symbols.loading) {
     return null;
   }
 
   return findClosestofSymbol(symbols.classes, location);
 }
--- a/devtools/client/debugger/new/src/utils/bootstrap.js
+++ b/devtools/client/debugger/new/src/utils/bootstrap.js
@@ -14,17 +14,17 @@ import { startSourceMapWorker, stopSourc
 import * as search from "../workers/search";
 import * as prettyPrint from "../workers/pretty-print";
 import * as parser from "../workers/parser";
 
 import configureStore from "../actions/utils/create-store";
 import reducers from "../reducers";
 import * as selectors from "../selectors";
 import App from "../components/App";
-import { asyncStore, prefs } from "./prefs";
+import { asyncStore } from "./prefs";
 
 function renderPanel(component, store) {
   const root = document.createElement("div");
   root.className = "launchpad-root theme-body";
   root.style.setProperty("flex", "1");
   const mount = document.querySelector("#mount");
   if (!mount) {
     return;
@@ -38,17 +38,17 @@ function renderPanel(component, store) {
 }
 
 export function bootstrapStore(
   client: any,
   { services, toolboxActions }: any,
   initialState: Object
 ) {
   const createStore = configureStore({
-    log: prefs.logging || isTesting(),
+    log: isTesting(),
     timing: isDevelopment(),
     makeThunkArgs: (args, state) => {
       return { ...args, client, ...services, ...toolboxActions };
     }
   });
 
   const store = createStore(combineReducers(reducers), initialState);
   store.subscribe(() => updatePrefs(store.getState()));
--- a/devtools/client/debugger/new/src/utils/breakpoint/astBreakpointLocation.js
+++ b/devtools/client/debugger/new/src/utils/breakpoint/astBreakpointLocation.js
@@ -4,22 +4,22 @@
 
 // @flow
 
 import { getSymbols } from "../../workers/parser";
 import { findClosestFunction } from "../ast";
 
 import type { SymbolDeclarations } from "../../workers/parser";
 
-import type { SourceLocation, Source, ASTLocation } from "../../types";
+import type { Location, Source, ASTLocation } from "../../types";
 
 export function getASTLocation(
   source: Source,
   symbols: SymbolDeclarations,
-  location: SourceLocation
+  location: Location
 ): ASTLocation {
   if (source.isWasm || !symbols || symbols.loading) {
     return { name: undefined, offset: location };
   }
 
   const scope = findClosestFunction(symbols, location);
   if (scope) {
     // we only record the line, but at some point we may
--- a/devtools/client/debugger/new/src/utils/breakpoint/index.js
+++ b/devtools/client/debugger/new/src/utils/breakpoint/index.js
@@ -9,17 +9,17 @@ 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 {
-  SourceLocation,
+  Location,
   PendingLocation,
   Breakpoint,
   PendingBreakpoint
 } from "../../types";
 
 import type { State } from "../../reducers/types";
 
 // Return the first argument that is a string, or null if nothing is a
@@ -28,37 +28,34 @@ export function firstString(...args: str
   for (const arg of args) {
     if (typeof arg === "string") {
       return arg;
     }
   }
   return null;
 }
 
-export function locationMoved(
-  location: SourceLocation,
-  newLocation: SourceLocation
-) {
+export function locationMoved(location: Location, newLocation: Location) {
   return (
     location.line !== newLocation.line || location.column !== newLocation.column
   );
 }
 
-export function makeLocationId(location: SourceLocation) {
+export function makeLocationId(location: Location) {
   const { sourceId, line, column } = location;
   const columnString = column || "";
   return `${sourceId}:${line}:${columnString}`;
 }
 
-export function getLocationWithoutColumn(location: SourceLocation) {
+export function getLocationWithoutColumn(location: Location) {
   const { sourceId, line } = location;
   return `${sourceId}:${line}`;
 }
 
-export function makePendingLocationId(location: SourceLocation) {
+export function makePendingLocationId(location: Location) {
   assertPendingLocation(location);
   const { sourceUrl, line, column } = location;
   const sourceUrlString = sourceUrl || "";
   const columnString = column || "";
 
   return `${sourceUrlString}:${line}:${columnString}`;
 }
 
@@ -67,17 +64,17 @@ export function assertBreakpoint(breakpo
   assertLocation(breakpoint.generatedLocation);
 }
 
 export function assertPendingBreakpoint(pendingBreakpoint: PendingBreakpoint) {
   assertPendingLocation(pendingBreakpoint.location);
   assertPendingLocation(pendingBreakpoint.generatedLocation);
 }
 
-export function assertLocation(location: SourceLocation) {
+export function assertLocation(location: Location) {
   assertPendingLocation(location);
   const { sourceId } = location;
   assert(!!sourceId, "location must have a source id");
 }
 
 export function assertPendingLocation(location: PendingLocation) {
   assert(!!location, "location must exist");
 
@@ -90,17 +87,17 @@ export function assertPendingLocation(lo
     location.hasOwnProperty("column") != null,
     "location must have a column"
   );
 }
 
 // syncing
 export function breakpointAtLocation(
   breakpoints: Breakpoint[],
-  { line, column }: SourceLocation
+  { line, column }: Location
 ) {
   return breakpoints.find(breakpoint => {
     const sameLine = breakpoint.location.line === line;
     if (!sameLine) {
       return false;
     }
 
     // NOTE: when column breakpoints are disabled we want to find
@@ -108,23 +105,23 @@ export function breakpointAtLocation(
     if (!features.columnBreakpoints) {
       return true;
     }
 
     return breakpoint.location.column === column;
   });
 }
 
-export function breakpointExists(state: State, location: SourceLocation) {
+export function breakpointExists(state: State, location: Location) {
   const currentBp = getBreakpoint(state, location);
   return currentBp && !currentBp.disabled;
 }
 
 export function createBreakpoint(
-  location: SourceLocation,
+  location: Location,
   overrides: Object = {}
 ): Breakpoint {
   const {
     condition,
     disabled,
     hidden,
     generatedLocation,
     astLocation,
--- a/devtools/client/debugger/new/src/utils/dbg.js
+++ b/devtools/client/debugger/new/src/utils/dbg.js
@@ -44,19 +44,18 @@ function bindSelectors(obj: Object): Obj
 }
 
 function getCM() {
   const cm: any = document.querySelector(".CodeMirror");
   return cm && cm.CodeMirror;
 }
 
 function _formatPausePoints(dbg: Object, url: string) {
-  const source =
-    dbg.helpers.findSource(url) || dbg.selectors.getSelectedSource();
-  const pausePoints = dbg.selectors.getPausePoints(source.id);
+  const source = dbg.helpers.findSource(url);
+  const pausePoints = dbg.selectors.getPausePoints(source);
   console.log(formatPausePoints(source.text, pausePoints));
 }
 
 function _formatColumnBreapoints(dbg: Object) {
   console.log(
     dbg.selectors.formatColumnBreakpoints(
       dbg.selectors.visibleColumnBreakpoints()
     )
--- a/devtools/client/debugger/new/src/utils/editor/get-expression.js
+++ b/devtools/client/debugger/new/src/utils/editor/get-expression.js
@@ -1,41 +1,41 @@
 /* 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 type { Position } from "../../types";
+import type { ColumnPosition } from "../../types";
 
 type Token = {
   startColumn: number,
   endColumn: number,
   type: string
 };
 
 export function tokenAtTextPosition(
   cm: any,
-  { line, column }: Position
+  { line, column }: ColumnPosition
 ): Token | null {
   if (line < 0 || line >= cm.lineCount()) {
     return null;
   }
 
   const token = cm.getTokenAt({ line: line - 1, ch: column });
   if (!token) {
     return null;
   }
 
   return { startColumn: token.start, endColumn: token.end, type: token.type };
 }
 
 // The strategy of querying codeMirror tokens was borrowed
 // from Chrome's inital implementation in JavaScriptSourceFrame.js#L414
-export function getExpressionFromCoords(cm: any, coord: Position) {
+export function getExpressionFromCoords(cm: any, coord: ColumnPosition) {
   const token = tokenAtTextPosition(cm, coord);
   if (!token) {
     return null;
   }
 
   let startHighlight = token.startColumn;
   const endHighlight = token.endColumn;
   const lineNumber = coord.line;
--- a/devtools/client/debugger/new/src/utils/editor/get-token-location.js
+++ b/devtools/client/debugger/new/src/utils/editor/get-token-location.js
@@ -1,19 +1,19 @@
 /* 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 type { Position } from "../../types";
+import type { ColumnPosition } from "../../types";
 
 export function getTokenLocation(
   codeMirror: any,
   tokenEl: HTMLElement
-): Position {
+): ColumnPosition {
   const { left, top, width, height } = tokenEl.getBoundingClientRect();
   const { line, ch } = codeMirror.coordsChar({
     left: left + width / 2,
     top: top + height / 2
   });
 
   return {
     line: line + 1,
--- a/devtools/client/debugger/new/src/utils/editor/index.js
+++ b/devtools/client/debugger/new/src/utils/editor/index.js
@@ -13,17 +13,17 @@ export { onMouseOver } from "./token-eve
 import { createEditor } from "./create-editor";
 import { shouldPrettyPrint, isOriginal } from "../source";
 import { findNext, findPrev } from "./source-search";
 
 import { isWasm, lineToWasmOffset, wasmOffsetToLine } from "../wasm";
 
 import type { AstLocation } from "../../workers/parser";
 import type { EditorPosition, EditorRange } from "../editor/types";
-import type { SourceLocation } from "../../types";
+import type { Location } from "../../types";
 type Editor = Object;
 
 let editor: ?Editor;
 
 export function getEditor() {
   if (editor) {
     return editor;
   }
@@ -91,17 +91,17 @@ export function toEditorLine(sourceId: s
   if (isWasm(sourceId)) {
     // TODO ensure offset is always "mappable" to edit line.
     return wasmOffsetToLine(sourceId, lineOrOffset) || 0;
   }
 
   return lineOrOffset ? lineOrOffset - 1 : 1;
 }
 
-export function toEditorPosition(location: SourceLocation): EditorPosition {
+export function toEditorPosition(location: Location): EditorPosition {
   return {
     line: toEditorLine(location.sourceId, location.line),
     column: isWasm(location.sourceId) || !location.column ? 0 : location.column
   };
 }
 
 export function toEditorRange(
   sourceId: string,
@@ -196,17 +196,17 @@ export function markText(_editor: any, c
 
 export function lineAtHeight(_editor, sourceId, event) {
   const _editorLine = _editor.codeMirror.lineAtHeight(event.clientY);
   return toSourceLine(sourceId, _editorLine);
 }
 
 export function getSourceLocationFromMouseEvent(
   _editor: Object,
-  selectedLocation: SourceLocation,
+  selectedLocation: Location,
   e: MouseEvent
 ) {
   const { line, ch } = _editor.codeMirror.coordsChar({
     left: e.clientX,
     top: e.clientY
   });
 
   return {
--- a/devtools/client/debugger/new/src/utils/location.js
+++ b/devtools/client/debugger/new/src/utils/location.js
@@ -1,28 +1,28 @@
 /* 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 type { SourceLocation, SourceId } from "../types";
+import type { Location, SourceId } from "../types";
 
 type IncompleteLocation = {
   sourceId: SourceId,
   line?: number,
   column?: number,
   sourceUrl?: string
 };
 
 export function createLocation({
   sourceId,
   line,
   column,
   sourceUrl
-}: IncompleteLocation): SourceLocation {
+}: IncompleteLocation): Location {
   return {
     sourceId,
     line: line || 0,
     column,
     sourceUrl: sourceUrl || ""
   };
 }
--- a/devtools/client/debugger/new/src/utils/log.js
+++ b/devtools/client/debugger/new/src/utils/log.js
@@ -7,24 +7,26 @@
 /**
  *
  * Utils for logging to the console
  * Suppresses logging in non-development environment
  *
  * @module utils/log
  */
 
-import { prefs } from "./prefs";
+import { isDevelopment } from "devtools-environment";
 
 /**
  * Produces a formatted console log line by imploding args, prefixed by [log]
  *
  * function input: log(["hello", "world"])
  * console output: [log] hello world
  *
  * @memberof utils/log
  * @static
  */
 export function log(...args: any[]) {
-  if (prefs.logging) {
-    console.log(...args);
+  if (!isDevelopment()) {
+    return;
   }
+
+  console.log.apply(console, ["[log]", ...args]);
 }
--- a/devtools/client/debugger/new/src/utils/pause/mapScopes/getApplicableBindingsForOriginalPosition.js
+++ b/devtools/client/debugger/new/src/utils/pause/mapScopes/getApplicableBindingsForOriginalPosition.js
@@ -4,40 +4,40 @@
 
 // @flow
 
 import type { BindingLocationType, BindingType } from "../../../workers/parser";
 import { positionCmp } from "./positionCmp";
 import { filterSortedArray } from "./filtering";
 import { mappingContains } from "./mappingContains";
 
-import type { Source, SourceLocation, PartialPosition } from "../../../types";
+import type { Source, Location, Position } from "../../../types";
 
 import type { GeneratedBindingLocation } from "./buildGeneratedBindingList";
 
 export type ApplicableBinding = {
   binding: GeneratedBindingLocation,
   range: GeneratedRange,
   firstInRange: boolean,
   firstOnLine: boolean
 };
 
 type GeneratedRange = {
-  start: PartialPosition,
-  end: PartialPosition
+  start: Position,
+  end: Position
 };
 
 export async function originalRangeStartsInside(
   source: Source,
   {
     start,
     end
   }: {
-    start: SourceLocation,
-    end: SourceLocation
+    start: Location,
+    end: Location
   },
   sourceMaps: any
 ) {
   const endPosition = await sourceMaps.getGeneratedLocation(end, source);
   const startPosition = await sourceMaps.getGeneratedLocation(start, source);
 
   // If the start and end positions collapse into eachother, it means that
   // the range in the original content didn't _start_ at the start position.
@@ -48,18 +48,18 @@ export async function originalRangeStart
 
 export async function getApplicableBindingsForOriginalPosition(
   generatedAstBindings: Array<GeneratedBindingLocation>,
   source: Source,
   {
     start,
     end
   }: {
-    start: SourceLocation,
-    end: SourceLocation
+    start: Location,
+    end: Location
   },
   bindingType: BindingType,
   locationType: BindingLocationType,
   sourceMaps: any
 ): Promise<Array<ApplicableBinding>> {
   const ranges = await sourceMaps.getGeneratedRanges(start, source);
 
   const resultRanges = ranges.map(mapRange => ({
--- a/devtools/client/debugger/new/src/utils/pause/mapScopes/index.js
+++ b/devtools/client/debugger/new/src/utils/pause/mapScopes/index.js
@@ -31,17 +31,17 @@ import {
 } from "./buildGeneratedBindingList";
 import {
   originalRangeStartsInside,
   getApplicableBindingsForOriginalPosition
 } from "./getApplicableBindingsForOriginalPosition";
 
 import { log } from "../../log";
 import type {
-  PartialPosition,
+  Position,
   Frame,
   Scope,
   Source,
   BindingContents,
   ScopeBindings
 } from "../../../types";
 
 export type OriginalScope = RenderableScope;
@@ -249,17 +249,17 @@ function batchScopeMappings(
       if (s !== source || !precalculatedLocations.has(key)) {
         log("Bad precalculated mapping");
         return sourceMaps.getGeneratedLocation(pos, s);
       }
       return precalculatedLocations.get(key);
     }
   };
 }
-function buildLocationKey(loc: PartialPosition): string {
+function buildLocationKey(loc: Position): string {
   return `${loc.line}:${locColumn(loc)}`;
 }
 
 function generateClientScope(
   scopes: Scope,
   originalScopes: Array<SourceScope & { generatedBindings: ScopeBindings }>
 ): OriginalScope {
   // Pull the root object scope and root lexical scope to reuse them in
--- a/devtools/client/debugger/new/src/utils/pause/mapScopes/locColumn.js
+++ b/devtools/client/debugger/new/src/utils/pause/mapScopes/locColumn.js
@@ -1,17 +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 <http://mozilla.org/MPL/2.0/>. */
 
 // @flow
 
-import type { PartialPosition } from "../../../types";
+import type { Position } from "../../../types";
 
-export function locColumn(loc: PartialPosition): number {
+export function locColumn(loc: Position): number {
   if (typeof loc.column !== "number") {
     // This shouldn't really happen with locations from the AST, but
     // the datatype we are using allows null/undefined column.
     return 0;
   }
 
   return loc.column;
 }
--- a/devtools/client/debugger/new/src/utils/pause/mapScopes/mappingContains.js
+++ b/devtools/client/debugger/new/src/utils/pause/mapScopes/mappingContains.js
@@ -1,18 +1,18 @@
 /* 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 type { PartialPosition } from "../../../types";
+import type { Position } from "../../../types";
 import { positionCmp } from "./positionCmp";
 
 export function mappingContains(
-  mapped: { +start: PartialPosition, +end: PartialPosition },
-  item: { +start: PartialPosition, +end: PartialPosition }
+  mapped: { +start: Position, +end: Position },
+  item: { +start: Position, +end: Position }
 ) {
   return (
     positionCmp(item.start, mapped.start) >= 0 &&
     positionCmp(item.end, mapped.end) <= 0
   );
 }
--- a/devtools/client/debugger/new/src/utils/pause/mapScopes/positionCmp.js
+++ b/devtools/client/debugger/new/src/utils/pause/mapScopes/positionCmp.js
@@ -1,23 +1,23 @@
 /* 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 type { PartialPosition } from "../../../types";
+import type { Position } from "../../../types";
 import { locColumn } from "./locColumn";
 
 /**
  * * === 0 - Positions are equal.
  * * < 0 - first position before second position
  * * > 0 - first position after second position
  */
-export function positionCmp(p1: PartialPosition, p2: PartialPosition) {
+export function positionCmp(p1: Position, p2: Position) {
   if (p1.line === p2.line) {
     const l1 = locColumn(p1);
     const l2 = locColumn(p2);
 
     if (l1 === l2) {
       return 0;
     }
     return l1 < l2 ? -1 : 1;
--- a/devtools/client/debugger/new/src/utils/pause/mapScopes/rangeMetadata.js
+++ b/devtools/client/debugger/new/src/utils/pause/mapScopes/rangeMetadata.js
@@ -4,17 +4,17 @@
 
 // @flow
 
 import { locColumn } from "./locColumn";
 import { positionCmp } from "./positionCmp";
 import { filterSortedArray } from "./filtering";
 
 import type { SourceScope } from "../../../workers/parser";
-import type { PartialPosition, Frame, Source } from "../../../types";
+import type { Position, Frame, Source } from "../../../types";
 
 type SourceOriginalRange = {
   line: number,
   columnStart: number,
   columnEnd: number
 };
 
 // * match - Range contains a single identifier with matching start location
@@ -113,17 +113,17 @@ export async function loadRangeMetadata(
       singleDeclaration,
       ...range
     };
   });
 }
 
 export function findMatchingRange(
   sortedOriginalRanges: Array<MappedOriginalRange>,
-  bindingRange: { +end: PartialPosition, +start: PartialPosition }
+  bindingRange: { +end: Position, +start: Position }
 ): ?MappedOriginalRange {
   return filterSortedArray(sortedOriginalRanges, range => {
     if (range.line < bindingRange.start.line) {
       return -1;
     }
     if (range.line > bindingRange.start.line) {
       return 1;
     }
--- a/devtools/client/debugger/new/src/utils/pause/pausePoints.js
+++ b/devtools/client/debugger/new/src/utils/pause/pausePoints.js
@@ -1,34 +1,38 @@
 /* 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 { reverse } from "lodash";
 
 import type { PausePoints } from "../../workers/parser";
-import type { Position } from "../../types";
+import type { ColumnPosition } from "../../types";
 
 type PausePoint = {
-  location: Position,
+  location: ColumnPosition,
   types: { break: boolean, step: boolean }
 };
 
 function insertStrtAt(string, index, newString) {
   const start = string.slice(0, index);
   const end = string.slice(index);
   return `${start}${newString}${end}`;
 }
 
 export function convertToList(pausePoints: PausePoints): PausePoint[] {
   const list = [];
   for (const line in pausePoints) {
     for (const column in pausePoints[line]) {
-      list.push(pausePoints[line][column]);
+      const point = pausePoints[line][column];
+      list.push({
+        location: { line: parseInt(line, 10), column: parseInt(column, 10) },
+        types: point
+      });
     }
   }
   return list;
 }
 
 export function formatPausePoints(text: string, pausePoints: PausePoints) {
   const nodes = reverse(convertToList(pausePoints));
   const lines = text.split("\n");
@@ -36,21 +40,8 @@ export function formatPausePoints(text: 
     const { line, column } = node.location;
     const { break: breakPoint, step } = node.types;
     const types = `${breakPoint ? "b" : ""}${step ? "s" : ""}`;
     lines[line - 1] = insertStrtAt(lines[line - 1], column, `/*${types}*/`);
   });
 
   return lines.join("\n");
 }
-
-export async function mapPausePoints(pausePoints, iteratee) {
-  const results = await Promise.all(convertToList(pausePoints).map(iteratee));
-
-  for (const line in pausePoints) {
-    const linePoints = pausePoints[line];
-    for (const column in linePoints) {
-      linePoints[column] = results.shift();
-    }
-  }
-
-  return pausePoints;
-}
--- a/devtools/client/debugger/new/src/utils/pause/stepping.js
+++ b/devtools/client/debugger/new/src/utils/pause/stepping.js
@@ -32,17 +32,17 @@ export function shouldStep(rootFrame: ?F
     return false;
   }
 
   const previousFrameLoc = getFrameLocation(selectedSource, previousFrameInfo);
   const frameLoc = getFrameLocation(selectedSource, rootFrame);
 
   const sameLocation = previousFrameLoc && isEqual(previousFrameLoc, frameLoc);
   const pausePoint = getPausePoint(state, frameLoc);
-  const invalidPauseLocation = pausePoint && !pausePoint.types.step;
+  const invalidPauseLocation = pausePoint && !pausePoint.step;
 
   // We always want to pause in generated locations
   if (!frameLoc || isGeneratedId(frameLoc.sourceId)) {
     return false;
   }
 
   return sameLocation || invalidPauseLocation;
 }
--- a/devtools/client/debugger/new/src/utils/prefs.js
+++ b/devtools/client/debugger/new/src/utils/prefs.js
@@ -9,17 +9,16 @@ import { isDevelopment } from "devtools-
 import Services from "devtools-services";
 import { asyncStoreHelper } from "./asyncStoreHelper";
 
 const prefsSchemaVersion = "1.0.5";
 
 const pref = Services.pref;
 
 if (isDevelopment()) {
-  pref("devtools.debugger.logging", false);
   pref("devtools.debugger.alphabetize-outline", false);
   pref("devtools.debugger.auto-pretty-print", false);
   pref("devtools.source-map.client-service.enabled", true);
   pref("devtools.debugger.pause-on-exceptions", false);
   pref("devtools.debugger.pause-on-caught-exceptions", false);
   pref("devtools.debugger.ignore-caught-exceptions", true);
   pref("devtools.debugger.call-stack-visible", true);
   pref("devtools.debugger.scopes-visible", true);
@@ -46,30 +45,30 @@ if (isDevelopment()) {
   pref("devtools.debugger.skip-pausing", false);
   pref("devtools.debugger.features.workers", true);
   pref("devtools.debugger.features.async-stepping", true);
   pref("devtools.debugger.features.wasm", true);
   pref("devtools.debugger.features.shortcuts", true);
   pref("devtools.debugger.features.root", true);
   pref("devtools.debugger.features.map-scopes", true);
   pref("devtools.debugger.features.remove-command-bar-options", true);
+  pref("devtools.debugger.features.event-listeners", false);
   pref("devtools.debugger.features.code-folding", false);
   pref("devtools.debugger.features.outline", true);
   pref("devtools.debugger.features.column-breakpoints", false);
   pref("devtools.debugger.features.pause-points", true);
   pref("devtools.debugger.features.skip-pausing", true);
   pref("devtools.debugger.features.component-pane", false);
   pref("devtools.debugger.features.autocomplete-expressions", false);
   pref("devtools.debugger.features.map-expression-bindings", true);
   pref("devtools.debugger.features.map-await-expression", true);
   pref("devtools.debugger.features.xhr-breakpoints", true);
 }
 
 export const prefs = new PrefsHelper("devtools", {
-  logging: ["Bool", "debugger.alphabetize-outline"],
   alphabetizeOutline: ["Bool", "debugger.alphabetize-outline"],
   autoPrettyPrint: ["Bool", "debugger.auto-pretty-print"],
   clientSourceMapsEnabled: ["Bool", "source-map.client-service.enabled"],
   pauseOnExceptions: ["Bool", "debugger.pause-on-exceptions"],
   pauseOnCaughtExceptions: ["Bool", "debugger.pause-on-caught-exceptions"],
   ignoreCaughtExceptions: ["Bool", "debugger.ignore-caught-exceptions"],
   callStackVisible: ["Bool", "debugger.call-stack-visible"],
   scopesVisible: ["Bool", "debugger.scopes-visible"],
@@ -100,16 +99,17 @@ export const features = new PrefsHelper(
   asyncStepping: ["Bool", "async-stepping"],
   wasm: ["Bool", "wasm"],
   shortcuts: ["Bool", "shortcuts"],
   root: ["Bool", "root"],
   columnBreakpoints: ["Bool", "column-breakpoints"],
   mapScopes: ["Bool", "map-scopes"],
   removeCommandBarOptions: ["Bool", "remove-command-bar-options"],
   workers: ["Bool", "workers"],
+  eventListeners: ["Bool", "event-listeners"],
   outline: ["Bool", "outline"],
   codeFolding: ["Bool", "code-folding"],
   pausePoints: ["Bool", "pause-points"],
   skipPausing: ["Bool", "skip-pausing"],
   autocompleteExpression: ["Bool", "autocomplete-expressions"],
   mapExpressionBindings: ["Bool", "map-expression-bindings"],
   mapAwaitExpression: ["Bool", "map-await-expression"],
   componentPane: ["Bool", "component-pane"],
--- a/devtools/client/debugger/new/src/utils/quick-open.js
+++ b/devtools/client/debugger/new/src/utils/quick-open.js
@@ -1,21 +1,16 @@
 /* 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 classnames from "classnames";
 import { endTruncateStr } from "./utils";
-import {
-  isPretty,
-  getFilename,
-  getSourceClassnames,
-  getSourceQueryString
-} from "./source";
+import { isPretty, getFilename, getSourceClassnames } from "./source";
 
 import type { Location as BabelLocation } from "@babel/types";
 import type { Symbols } from "../reducers/ast";
 import type { QuickOpenType } from "../reducers/quick-open";
 import type { TabList } from "../reducers/tabs";
 import type { Source } from "../types";
 import type { SymbolDeclaration } from "../workers/parser";
 
@@ -53,23 +48,19 @@ export function parseLineColumn(query: s
       line: lineNumber,
       ...(!isNaN(columnNumber) ? { column: columnNumber } : null)
     };
   }
 }
 
 export function formatSourcesForList(source: Source, tabs: TabList) {
   const title = getFilename(source);
-  const relativeUrlWithQuery = `${source.relativeUrl}${getSourceQueryString(
-    source
-  )}`;
-  const subtitle = endTruncateStr(relativeUrlWithQuery, 100);
-  const value = relativeUrlWithQuery;
+  const subtitle = endTruncateStr(source.relativeUrl, 100);
   return {
-    value,
+    value: source.relativeUrl,
     title,
     subtitle,
     icon: tabs.some(tab => tab.url == source.url)
       ? "tab result-item-icon"
       : classnames(getSourceClassnames(source), "result-item-icon"),
     id: source.id,
     url: source.url
   };
@@ -97,22 +88,23 @@ export function formatSymbol(symbol: Sym
     subtitle: `${symbol.location.start.line}`,
     value: symbol.name,
     location: symbol.location
   };
 }
 
 export function formatSymbols(symbols: ?Symbols): FormattedSymbolDeclarations {
   if (!symbols || symbols.loading) {
-    return { functions: [] };
+    return { variables: [], functions: [] };
   }
 
-  const { functions } = symbols;
+  const { variables, functions } = symbols;
 
   return {
+    variables: variables.map(formatSymbol),
     functions: functions.map(formatSymbol)
   };
 }
 
 export function formatShortcutResults(): Array<QuickOpenResult> {
   return [
     {
       value: L10N.getStr("symbolSearch.search.functionsPlaceholder.title"),
--- a/devtools/client/debugger/new/src/utils/source-maps.js
+++ b/devtools/client/debugger/new/src/utils/source-maps.js
@@ -2,25 +2,25 @@
  * 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 { isOriginalId } from "devtools-source-map";
 import { getSource } from "../selectors";
 
-import type { SourceLocation, MappedLocation, Source } from "../types";
+import type { Location, MappedLocation, Source } from "../types";
 import { isGenerated } from "../utils/source";
 
 export async function getGeneratedLocation(
   state: Object,
   source: Source,
-  location: SourceLocation,
+  location: Location,
   sourceMaps: Object
-): Promise<SourceLocation> {
+): Promise<Location> {
   if (!isOriginalId(location.sourceId)) {
     return location;
   }
 
   const { line, sourceId, column } = await sourceMaps.getGeneratedLocation(
     location,
     source
   );
@@ -36,18 +36,18 @@ export async function getGeneratedLocati
     column: column === 0 ? undefined : column,
     sourceUrl: generatedSource.url
   };
 }
 
 export async function getMappedLocation(
   state: Object,
   sourceMaps: Object,
-  location: SourceLocation
-): Promise<SourceLocation> {
+  location: Location
+): Promise<Location> {
   const source = getSource(state, location.sourceId);
 
   if (!source) {
     return location;
   }
 
   if (isOriginalId(location.sourceId)) {
     return getGeneratedLocation(state, source, location, sourceMaps);
--- a/devtools/client/debugger/new/src/utils/source.js
+++ b/devtools/client/debugger/new/src/utils/source.js
@@ -16,17 +16,17 @@ import { endTruncateStr } from "./utils"
 import { truncateMiddleText } from "../utils/text";
 import { parse as parseURL } from "../utils/url";
 import { renderWasmText } from "./wasm";
 import { toEditorPosition } from "./editor";
 export { isMinified } from "./isMinified";
 import { getURL, getFileExtension } from "./sources-tree";
 import { prefs } from "./prefs";
 
-import type { Source, SourceLocation, JsSource } from "../types";
+import type { Source, Location, JsSource } from "../types";
 import type { SourceMetaDataType } from "../reducers/ast";
 import type { SymbolDeclarations } from "../workers/parser";
 
 type transformUrlCallback = string => string;
 
 export const sourceTypes = {
   coffee: "coffeescript",
   js: "javascript",
@@ -381,17 +381,17 @@ export function getMode(
 export function isLoaded(source: Source) {
   return source.loadedState === "loaded";
 }
 
 export function isLoading(source: Source) {
   return source.loadedState === "loading";
 }
 
-export function getTextAtPosition(source: ?Source, location: SourceLocation) {
+export function getTextAtPosition(source: ?Source, location: Location) {
   if (!source || !source.text) {
     return "";
   }
 
   const line = location.line;
   const column = location.column || 0;
 
   if (source.isWasm) {
--- a/devtools/client/debugger/new/src/workers/parser/getScopes/index.js
+++ b/devtools/client/debugger/new/src/workers/parser/getScopes/index.js
@@ -22,21 +22,21 @@ export type {
   BindingData,
   BindingDeclarationLocation,
   BindingLocation,
   BindingLocationType,
   BindingMetaValue,
   BindingType
 };
 
-import type { SourceLocation } from "../../../types";
+import type { Location } from "../../../types";
 
 let parsedScopesCache = new Map();
 
-export default function getScopes(location: SourceLocation): SourceScope[] {
+export default function getScopes(location: Location): SourceScope[] {
   const { sourceId } = location;
   let parsedScopes = parsedScopesCache.get(sourceId);
   if (!parsedScopes) {
     parsedScopes = parseSourceScopes(sourceId);
     parsedScopesCache.set(sourceId, parsedScopes);
   }
   return parsedScopes ? findScopes(parsedScopes, location) : [];
 }
@@ -45,20 +45,17 @@ export function clearScopes() {
   parsedScopesCache = new Map();
 }
 
 export { buildScopeList };
 
 /**
  * Searches all scopes and their bindings at the specific location.
  */
-function findScopes(
-  scopes: ParsedScope[],
-  location: SourceLocation
-): SourceScope[] {
+function findScopes(scopes: ParsedScope[], location: Location): SourceScope[] {
   // Find inner most in the tree structure.
   let searchInScopes: ?(ParsedScope[]) = scopes;
   const found = [];
   while (searchInScopes) {
     const foundOne = searchInScopes.some(s => {
       if (
         compareLocations(s.start, location) <= 0 &&
         compareLocations(location, s.end) < 0
@@ -80,14 +77,14 @@ function findScopes(
       displayName: i.displayName,
       start: i.start,
       end: i.end,
       bindings: i.bindings
     };
   });
 }
 
-function compareLocations(a: SourceLocation, b: SourceLocation): number {
+function compareLocations(a: Location, b: Location): number {
   // According to type of Location.column can be undefined, if will not be the
   // case here, ignoring flow error.
   // $FlowIgnore
   return a.line == b.line ? a.column - b.column : a.line - b.line;
 }
--- a/devtools/client/debugger/new/src/workers/parser/index.js
+++ b/devtools/client/debugger/new/src/workers/parser/index.js
@@ -3,17 +3,17 @@
  * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
 
 // @flow
 
 import { workerUtils } from "devtools-utils";
 const { WorkerDispatcher } = workerUtils;
 
 import type { AstLocation, AstPosition, PausePoints } from "./types";
-import type { SourceLocation, Source, SourceId } from "../../types";
+import type { Location, Source, SourceId } from "../../types";
 import type { SourceScope } from "./getScopes/visitor";
 import type { SymbolDeclarations } from "./getSymbols";
 
 const dispatcher = new WorkerDispatcher();
 export const start = (url: string, win: any = window) =>
   dispatcher.start(url, win);
 export const stop = () => dispatcher.stop();
 
@@ -21,25 +21,24 @@ export const findOutOfScopeLocations = a
   sourceId: string,
   position: AstPosition
 ): Promise<AstLocation[]> =>
   dispatcher.invoke("findOutOfScopeLocations", sourceId, position);
 
 export const getNextStep = async (
   sourceId: SourceId,
   pausedPosition: AstPosition
-): Promise<?SourceLocation> =>
+): Promise<?Location> =>
   dispatcher.invoke("getNextStep", sourceId, pausedPosition);
 
 export const clearASTs = async (): Promise<void> =>
   dispatcher.invoke("clearASTs");
 
-export const getScopes = async (
-  location: SourceLocation
-): Promise<SourceScope[]> => dispatcher.invoke("getScopes", location);
+export const getScopes = async (location: Location): Promise<SourceScope[]> =>
+  dispatcher.invoke("getScopes", location);
 
 export const clearScopes = async (): Promise<void> =>
   dispatcher.invoke("clearScopes");
 
 export const clearSymbols = async (): Promise<void> =>
   dispatcher.invoke("clearSymbols");
 
 export const getSymbols = async (
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints-actions.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints-actions.js
@@ -3,25 +3,25 @@
 
 function openFirstBreakpointContextMenu(dbg){
   rightClickElement(dbg, "breakpointItem", 3);
 }
 
 
 // Tests to see if we can trigger a breakpoint action via the context menu
 add_task(async function() {
-  const dbg = await initDebugger("doc-scripts.html", "simple2");
+  const dbg = await initDebugger("doc-scripts.html");
   await selectSource(dbg, "simple2");
   await waitForSelectedSource(dbg, "simple2");
 
   await addBreakpoint(dbg, "simple2", 3);
 
   openFirstBreakpointContextMenu(dbg)
   // select "Remove breakpoint"
-  selectContextMenuItem(dbg, selectors.breakpointContextMenu.remove);
+  selectMenuItem(dbg, 1);
 
   await waitForState(dbg, state => dbg.selectors.getBreakpointCount(state) === 0);
   ok("successfully removed the breakpoint");
 });
 
 // Tests "disable others", "enable others" and "remove others" context actions
 add_task(async function() {
   const dbg = await initDebugger("doc-scripts.html");
@@ -31,48 +31,48 @@ add_task(async function() {
   await addBreakpoint(dbg, "simple1", 1);
   await addBreakpoint(dbg, "simple1", 4);
   await addBreakpoint(dbg, "simple1", 5);
   await addBreakpoint(dbg, "simple1", 6);
 
   openFirstBreakpointContextMenu(dbg);
   // select "Disable Others"
   let dispatched = waitForDispatch(dbg, "DISABLE_BREAKPOINT", 3);
-  selectContextMenuItem(dbg, selectors.breakpointContextMenu.disableOthers);
+  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);
   // select "Disable All"
   dispatched = waitForDispatch(dbg, "DISABLE_ALL_BREAKPOINTS");
-  selectContextMenuItem(dbg, selectors.breakpointContextMenu.disableAll);
+  selectMenuItem(dbg, 9);
   await waitForState(dbg, state =>
     dbg.selectors.getBreakpointsList(state).every(bp => bp.disabled)
   );
   await dispatched;
   ok("all breakpoints are disabled");
 
   openFirstBreakpointContextMenu(dbg);
   // select "Enable Others"
   dispatched = waitForDispatch(dbg, "ENABLE_BREAKPOINT", 3);
-  selectContextMenuItem(dbg, selectors.breakpointContextMenu.enableOthers);
+  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);
   // select "Remove Others"
   dispatched = waitForDispatch(dbg, "REMOVE_BREAKPOINT", 3);
-  selectContextMenuItem(dbg, selectors.breakpointContextMenu.removeOthers);
+  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");
 });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints-cond.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints-cond.js
@@ -33,36 +33,29 @@ function waitForElementFocus(dbg, el) {
 }
 
 async function assertConditionalBreakpointIsFocused(dbg) {
   const input = findElement(dbg, "conditionalPanelInput");
   await waitForElementFocus(dbg, input);
 }
 
 async function setConditionalBreakpoint(dbg, index, condition) {
-  const {
-    addConditionalBreakpoint,
-    editBreakpoint
-  } = selectors.gutterContextMenu;
-  // Make this work with either add or edit menu items
-  const selector = `${addConditionalBreakpoint},${editBreakpoint}`;
-
   rightClickElement(dbg, "gutter", index);
-  selectContextMenuItem(dbg, selector);
+  selectMenuItem(dbg, 2);
   await waitForElement(dbg, "conditionalPanelInput");
   await assertConditionalBreakpointIsFocused(dbg);
 
   // Position cursor reliably at the end of the text.
   pressKey(dbg, "End");
   type(dbg, condition);
   pressKey(dbg, "Enter");
 }
 
 add_task(async function() {
-  const dbg = await initDebugger("doc-scripts.html", "simple2");
+  const dbg = await initDebugger("doc-scripts.html");
   await selectSource(dbg, "simple2");
   await waitForSelectedSource(dbg, "simple2");
 
   await setConditionalBreakpoint(dbg, 5, "1");
   await waitForDispatch(dbg, "ADD_BREAKPOINT");
   let bp = findBreakpoint(dbg, "simple2", 5);
   is(bp.condition, "1", "breakpoint is created with the condition");
   assertEditorBreakpoint(dbg, 5, true);
@@ -88,13 +81,13 @@ add_task(async function() {
   bp = findBreakpoint(dbg, "simple2", 5);
   is(bp.condition, "1", "breakpoint is created with the condition");
   assertEditorBreakpoint(dbg, 5, true);
 
   const bpCondition = waitForDispatch(dbg, "SET_BREAKPOINT_CONDITION");
   //right click breakpoint in breakpoints list
   rightClickElement(dbg, "breakpointItem", 3)
   // select "remove condition";
-  selectContextMenuItem(dbg, selectors.breakpointContextMenu.removeCondition);
+  selectMenuItem(dbg, 8);
   await bpCondition;
   bp = findBreakpoint(dbg, "simple2", 5);
   is(bp.condition, undefined, "breakpoint condition removed");
 });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints-reloading.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints-reloading.js
@@ -20,17 +20,17 @@ function addBreakpoint(dbg, line) {
 }
 
 function assertEditorBreakpoint(dbg, line) {
   const exists = !!getLineEl(dbg, line).querySelector(".new-breakpoint");
   ok(exists, `Breakpoint exists on line ${line}`);
 }
 
 add_task(async function() {
-  const dbg = await initDebugger("doc-scripts.html", "simple1.js");
+  const dbg = await initDebugger("doc-scripts.html");
   const {
     selectors: { getBreakpoints, getBreakpoint },
     getState
   } = dbg;
   const source = findSource(dbg, "simple1.js");
 
   await selectSource(dbg, source.url);
   await addBreakpoint(dbg, 5);
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints.js
@@ -39,19 +39,18 @@ function findBreakpoint(dbg, url, line) 
   const {
     selectors: { getBreakpoint },
     getState
   } = dbg;
   const source = findSource(dbg, url);
   return getBreakpoint(getState(), { sourceId: source.id, line });
 }
 
-// Test enabling and disabling a breakpoint using the check boxes
 add_task(async function() {
-  const dbg = await initDebugger("doc-scripts.html", "simple2");
+  const dbg = await initDebugger("doc-scripts.html");
 
   // Create two breakpoints
   await selectSource(dbg, "simple2");
   await addBreakpoint(dbg, "simple2", 3);
   await addBreakpoint(dbg, "simple2", 5);
 
   // Disable the first one
   await disableBreakpoint(dbg, 0);
@@ -61,36 +60,8 @@ add_task(async function() {
   is(bp2.disabled, false, "second breakpoint is enabled");
 
   // Disable and Re-Enable the second one
   await disableBreakpoint(dbg, 1);
   await enableBreakpoint(dbg, 1);
   bp2 = findBreakpoint(dbg, "simple2", 5);
   is(bp2.disabled, false, "second breakpoint is enabled");
 });
-
-// Test enabling and disabling a breakpoint using the context menu
-add_task(async function() {
-  const dbg = await initDebugger("doc-scripts.html");
-  await selectSource(dbg, "simple2");
-  await addBreakpoint(dbg, "simple2", 3);
-  await addBreakpoint(dbg, "simple2", 5);
-
-  rightClickElement(dbg, "breakpointItem", 3);
-  const disableBreakpointDispatch = waitForDispatch(dbg, "DISABLE_BREAKPOINT");
-  selectContextMenuItem(dbg, selectors.breakpointContextMenu.disableSelf);
-  await disableBreakpointDispatch;
-
-  let bp1 = findBreakpoint(dbg, "simple2", 3);
-  let bp2 = findBreakpoint(dbg, "simple2", 5);
-  is(bp1.disabled, true, "first breakpoint is disabled");
-  is(bp2.disabled, false, "second breakpoint is enabled");
-
-  rightClickElement(dbg, "breakpointItem", 3);
-  const enableBreakpointDispatch = waitForDispatch(dbg, "ENABLE_BREAKPOINT");
-  selectContextMenuItem(dbg, selectors.breakpointContextMenu.enableSelf);
-  await enableBreakpointDispatch;
-
-  bp1 = findBreakpoint(dbg, "simple2", 3);
-  bp2 = findBreakpoint(dbg, "simple2", 5);
-  is(bp1.disabled, false, "first breakpoint is enabled");
-  is(bp2.disabled, false, "second breakpoint is enabled");
-});
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-console-async.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-console-async.js
@@ -35,17 +35,17 @@ async function hasMessage(dbg, msg) {
     msg
   ).length > 0)
 }
 
 add_task(async function() {
   Services.prefs.setBoolPref("devtools.toolbox.splitconsoleEnabled", true);
   Services.prefs.setBoolPref("devtools.debugger.features.map-await-expression", true);
 
-  const dbg = await initDebugger("doc-script-switching.html", "switching-01");
+  const dbg = await initDebugger("doc-script-switching.html");
 
   await selectSource(dbg, "switching-01");
 
   // open the console
   await getSplitConsole(dbg);
   ok(dbg.toolbox.splitConsole, "Split console is shown.");
 
   const webConsole = await dbg.toolbox.getPanel("webconsole")
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-console.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-console.js
@@ -18,17 +18,17 @@ function getSplitConsole(dbg) {
       let jsterm = toolbox.getPanel("webconsole").hud.jsterm;
       resolve(jsterm);
     });
   });
 }
 
 add_task(async function() {
   Services.prefs.setBoolPref("devtools.toolbox.splitconsoleEnabled", true);
-  const dbg = await initDebugger("doc-script-switching.html", "switching-01");
+  const dbg = await initDebugger("doc-script-switching.html");
 
   await selectSource(dbg, "switching-01");
 
   // open the console
   await getSplitConsole(dbg);
   ok(dbg.toolbox.splitConsole, "Split console is shown.");
 
   // close the console
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-editor-gutter.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-editor-gutter.js
@@ -21,17 +21,17 @@ function assertEditorBreakpoint(dbg, lin
     "Breakpoint " +
       (shouldExist ? "exists" : "does not exist") +
       " on line " +
       line
   );
 }
 
 add_task(async function() {
-  const dbg = await initDebugger("doc-scripts.html", "simple1.js");
+  const dbg = await initDebugger("doc-scripts.html");
   const {
     selectors: { getBreakpoint, getBreakpointCount },
     getState
   } = dbg;
   const source = findSource(dbg, "simple1.js");
 
   await selectSource(dbg, source.url);
 
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-editor-highlight.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-editor-highlight.js
@@ -1,17 +1,17 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Tests that the editor will always highight the right line, no
 // matter if the source text doesn't exist yet or even if the source
 // doesn't exist.
 
 add_task(async function() {
-  const dbg = await initDebugger("doc-scripts.html", "long.js");
+  const dbg = await initDebugger("doc-scripts.html");
   const {
     selectors: { getSource },
     getState
   } = dbg;
   const sourceUrl = EXAMPLE_URL + "long.js";
 
   // The source itself doesn't even exist yet, and using
   // `selectSourceURL` will set a pending request to load this source
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-editor-mode.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-editor-mode.js
@@ -1,14 +1,14 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Tests that the editor sets the correct mode for different file
 // types
 add_task(async function() {
-  const dbg = await initDebugger("doc-scripts.html", "simple1.js");
+  const dbg = await initDebugger("doc-scripts.html");
 
   await selectSource(dbg, "simple1.js");
   is(dbg.win.cm.getOption("mode").name, "javascript", "Mode is correct");
 
   await selectSource(dbg, "doc-scripts.html");
   is(dbg.win.cm.getOption("mode").name, "htmlmixed", "Mode is correct");
 });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-keyboard-navigation.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-keyboard-navigation.js
@@ -1,15 +1,15 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Tests that keyboard navigation into and out of debugger code editor
 
 add_task(async function() {
-  const dbg = await initDebugger("doc-scripts.html", "simple2");
+  const dbg = await initDebugger("doc-scripts.html");
   let doc = dbg.win.document;
 
   await selectSource(dbg, "simple2");
 
   await waitForElementWithSelector(dbg, ".CodeMirror");
   findElementWithSelector(dbg, ".CodeMirror").focus();
 
   // Enter code editor
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-minified.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-minified.js
@@ -9,17 +9,19 @@ function getScopeNodeLabel(dbg, index) {
 
 function getScopeNodeValue(dbg, index) {
   return findElement(dbg, "scopeValue", index).innerText;
 }
 
 add_task(async function() {
   await pushPref("devtools.debugger.features.map-scopes", true);
 
-  const dbg = await initDebugger("doc-minified2.html", "sum.js");
+  const dbg = await initDebugger("doc-minified2.html");
+
+  await waitForSources(dbg, "sum.js");
 
   await selectSource(dbg, "sum.js");
   await addBreakpoint(dbg, "sum.js", 2);
 
   invokeInTab("test");
   await waitForPaused(dbg);
 
   is(getScopeNodeLabel(dbg, 1), "sum", "check scope label");
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-outline-filter.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-outline-filter.js
@@ -6,17 +6,17 @@ function getItems(dbg) {
 }
 
 function getNthItem(dbg, index) {
   return findElement(dbg, "outlineItem", index);
 }
 
 // Tests the outline pane fuzzy filtering of outline items
 add_task(async function() {
-  const dbg = await initDebugger("doc-scripts.html", "long");
+  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"
   );
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-outline-pretty.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-outline-pretty.js
@@ -6,17 +6,17 @@ function getItems(dbg) {
 }
 
 function getNthItem(dbg, index) {
   return findElement(dbg, "outlineItem", index);
 }
 
 // Tests that the length of outline functions for original and pretty printed source matches
 add_task(async function () {
-  const dbg = await initDebugger("doc-scripts.html", "simple1");
+  const dbg = await initDebugger("doc-scripts.html");
   const {
     selectors: { getSelectedSource },
     getState
   } = dbg;
 
   await selectSource(dbg, "simple1");
   findElementWithSelector(dbg, ".outline-tab").click();
   const originalSource = getItems(dbg);
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-outline.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-outline.js
@@ -6,17 +6,17 @@ function getItems(dbg) {
 }
 
 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", "simple1");
+  const dbg = await initDebugger("doc-scripts.html");
   const {
     selectors: { getSelectedSource },
     getState
   } = dbg;
 
   await selectSource(dbg, "simple1", 1);
 
   findElementWithSelector(dbg, ".outline-tab").click();
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-pause-points.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-pause-points.js
@@ -24,17 +24,17 @@ async function testCase(dbg, { name, cou
     locations.push([line, column]);
   });
 
   is(formatSteps(locations), formatSteps(steps), name);
   await resume(dbg);
 }
 
 add_task(async function test() {
-  const dbg = await initDebugger("doc-pause-points.html", "pause-points.js");
+  const dbg = await initDebugger("doc-pause-points.html");
 
   await selectSource(dbg, "pause-points.js")
   await testCase(dbg, {
     name: "statements",
     count: 7,
     steps: [[9,2], [10,4], [10,13], [11,2], [11,21], [12,2], [12,12], [13,0]]
   });
 
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-pretty-print-paused.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-pretty-print-paused.js
@@ -1,15 +1,15 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Tests pretty-printing a source that is currently paused.
 
 add_task(async function() {
-  const dbg = await initDebugger("doc-minified.html", "math.min.js");
+  const dbg = await initDebugger("doc-minified.html");
 
   await selectSource(dbg, "math.min.js");
   await addBreakpoint(dbg, "math.min.js", 2);
 
   invokeInTab("arithmetic");
   await waitForPaused(dbg);
   assertPausedLocation(dbg);
 
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-pretty-print.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-pretty-print.js
@@ -1,15 +1,15 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Tests basic pretty-printing functionality.
 
 add_task(async function() {
-  const dbg = await initDebugger("doc-minified.html", "math.min.js");
+  const dbg = await initDebugger("doc-minified.html");
 
   await selectSource(dbg, "math.min.js", 2);
   clickElement(dbg, "prettyPrintButton");
 
   await waitForSelectedSource(dbg, "math.min.js:formatted");
   const ppSrc = findSource(dbg, "math.min.js:formatted");
 
   ok(ppSrc, "Pretty-printed source exists");
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-preview-source-maps.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-preview-source-maps.js
@@ -28,22 +28,23 @@ function assertPreviewPopup(dbg, { field
     value,
     "Preview.result"
   );
   is(preview.updating, false, "Preview.updating");
   is(preview.expression, expression, "Preview.expression");
 }
 
 add_task(async function() {
-  const dbg = await initDebugger("doc-sourcemaps.html", "entry.js", "output.js", "times2.js", "opts.js");
+  const dbg = await initDebugger("doc-sourcemaps.html");
   const {
     selectors: { getSelectedSource },
     getState
   } = dbg;
 
+  await waitForSources(dbg, "entry.js", "output.js", "times2.js", "opts.js");
   await selectSource(dbg, "times2");
   await addBreakpoint(dbg, "times2", 2);
 
   invokeInTab("keepMeAlive");
   await waitForPaused(dbg);
   await waitForSelectedSource(dbg, "times2");
 
   info(`Test previewing in the original location`);
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-preview.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-preview.js
@@ -9,17 +9,17 @@ async function previews(dbg, fnName, pre
   await resume(dbg);
 
   info(`Ran tests for ${fnName}`);
 }
 
 // Test hovering on an object, which will show a popup and on a
 // simple value, which will show a tooltip.
 add_task(async function() {
-  const dbg = await initDebugger("doc-preview.html", "preview.js");
+  const dbg = await initDebugger("doc-preview.html");
   await selectSource(dbg, "preview.js");
 
   await previews(dbg, "empties", [
     // { line: 2, column: 9, expression: "a", result: '""' },
     // { line: 3, column: 9, expression: "b", result: "false" },
     { line: 4, column: 9, expression: "c", result: "undefined" },
     { line: 5, column: 9, expression: "d", result: "null" }
   ]);
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-quick-open.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-quick-open.js
@@ -105,16 +105,26 @@ add_task(async function() {
   is(resultCount(dbg), 2, "two function results");
 
   type(dbg, "@x");
   is(resultCount(dbg), 0, "no functions with 'x' in name");
 
   pressKey(dbg, "Escape");
   assertDisabled(dbg);
 
+  info("Testing variable search");
+  quickOpen(dbg, "sw2");
+  pressKey(dbg, "Enter");
+
+  quickOpen(dbg, "#");
+  is(resultCount(dbg), 1, "one variable result");
+  const results = findAllElements(dbg, "resultItems");
+  results.forEach(result => is(result.textContent, "x13"));
+  await waitToClose(dbg);
+
   info("Testing goto line:column");
   assertLine(dbg, 0);
   assertColumn(dbg, null);
   quickOpen(dbg, ":7:12");
   pressKey(dbg, "Enter");
   assertLine(dbg, 7);
   assertColumn(dbg, 12);
 
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-react-app.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-react-app.js
@@ -1,13 +1,15 @@
 add_task(async function() {
   const dbg = await initDebugger("doc-react.html", "App.js");
 
+  await waitForSource(dbg, "App.js");
   await addBreakpoint(dbg, "App.js", 11);
 
+
   info('Test previewing an immutable Map inside of a react component')
   invokeInTab("clickButton");
   await waitForPaused(dbg);
   await waitForState(
     dbg,
     state => dbg.selectors.getSelectedScopeMappings(state)
   );
 
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-reloading.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-reloading.js
@@ -13,18 +13,19 @@ async function waitForBreakpoint(dbg, lo
     state => {
       return dbg.selectors.getBreakpoint(dbg.getState(), location);
     },
     "Waiting for breakpoint"
   );
 }
 
 add_task(async function() {
-  const dbg = await initDebugger("ember/quickstart/dist/", "ember-application/index.js");
+  const dbg = await initDebugger("ember/quickstart/dist/");
 
+  await waitForSource(dbg, "ember-application/index.js");
   await selectSource(dbg, "ember-application/index.js");
 
   info("1. reload and hit breakpoint")
   await addBreakpoint(dbg, "ember-application/index.js", 4);
   reload(dbg, "ember/quickstart/dist/");
 
   info("2. Wait for sources to appear and then reload")
   await waitForDispatch(dbg, "ADD_SOURCES")
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-search-file.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-search-file.js
@@ -8,17 +8,17 @@ function waitForSearchState(dbg) {
 }
 
 function getFocusedEl(dbg) {
   let doc = dbg.win.document;
   return doc.activeElement;
 }
 
 add_task(async function() {
-  const dbg = await initDebugger("doc-scripts.html", "simple1.js");
+  const dbg = await initDebugger("doc-scripts.html");
   const {
     selectors: { getBreakpoints, getBreakpoint, getActiveSearch },
     getState
   } = dbg;
   const source = findSource(dbg, "simple1.js");
 
   await selectSource(dbg, source.url);
 
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemaps.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemaps.js
@@ -34,22 +34,23 @@ function getLineEl(dbg, line) {
 }
 
 function clickGutter(dbg, line) {
   clickElement(dbg, "gutter", line);
 }
 
 add_task(async function() {
   // NOTE: the CORS call makes the test run times inconsistent
-  const dbg = await initDebugger("doc-sourcemaps.html", "entry.js", "output.js", "times2.js", "opts.js");
+  const dbg = await initDebugger("doc-sourcemaps.html");
   const {
     selectors: { getBreakpoint, getBreakpointCount },
     getState
   } = dbg;
 
+  await waitForSources(dbg, "entry.js", "output.js", "times2.js", "opts.js");
   ok(true, "Original sources exist");
   const bundleSrc = findSource(dbg, "bundle.js");
 
   await selectSource(dbg, bundleSrc);
 
   await clickGutter(dbg, 13);
   await waitForDispatch(dbg, "ADD_BREAKPOINT");
   assertEditorBreakpoint(dbg, 13, true);
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemaps2.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemaps2.js
@@ -13,22 +13,24 @@ function assertBpInGutter(dbg, lineNumbe
 }
 
 // Tests loading sourcemapped sources, setting breakpoints, and
 // stepping in them.
 
 // This source map does not have source contents, so it's fetched separately
 add_task(async function() {
   // NOTE: the CORS call makes the test run times inconsistent
-  const dbg = await initDebugger("doc-sourcemaps2.html", "main.js", "main.min.js");
+  const dbg = await initDebugger("doc-sourcemaps2.html");
   const {
     selectors: { getBreakpoint, getBreakpointCount },
     getState
   } = dbg;
 
+  await waitForSources(dbg, "main.js", "main.min.js");
+
   ok(true, "Original sources exist");
   const mainSrc = findSource(dbg, "main.js");
 
   await selectSource(dbg, mainSrc);
 
   // Test that breakpoint is not off by a line.
   await addBreakpoint(dbg, mainSrc, 4);
   is(getBreakpointCount(getState()), 1, "One breakpoint exists");
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemaps3.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-sourcemaps3.js
@@ -5,22 +5,24 @@
 // inspecting restored scopes.
 requestLongerTimeout(2);
 
 // This source map does not have source contents, so it's fetched separately
 add_task(async function() {
   // NOTE: the CORS call makes the test run times inconsistent
   await pushPref("devtools.debugger.features.map-scopes", true);
 
-  const dbg = await initDebugger("doc-sourcemaps3.html", "bundle.js", "sorted.js", "test.js");
+  const dbg = await initDebugger("doc-sourcemaps3.html");
   const {
     selectors: { getBreakpoint, getBreakpointCount },
     getState
   } = dbg;
 
+  await waitForSources(dbg, "bundle.js", "sorted.js", "test.js");
+
   ok(true, "Original sources exist");
   const sortedSrc = findSource(dbg, "sorted.js");
 
   await selectSource(dbg, sortedSrc);
 
   // Test that breakpoint is not off by a line.
   await addBreakpoint(dbg, sortedSrc, 9);
   is(getBreakpointCount(getState()), 1, "One breakpoint exists");
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-sources-arrow-keys.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-sources-arrow-keys.js
@@ -1,14 +1,15 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Test keyboard arrow behaviour
 add_task(async function() {
-  const dbg = await initDebugger("doc-sources.html", "simple1", "simple2", "nested-source", "long.js");
+  const dbg = await initDebugger("doc-sources.html");
+  await waitForSources(dbg, "simple1", "simple2", "nested-source", "long.js");
 
   await clickElement(dbg, "sourceDirectoryLabel", 2);
   await assertSourceCount(dbg, 7);
 
   // Right key on open dir
   await pressKey(dbg, "Right");
   await assertNodeIsFocused(dbg, 3);
 
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-sources-named-eval.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-sources-named-eval.js
@@ -13,23 +13,26 @@ async function waitForSourceCount(dbg, i
 
 function getLabel(dbg, index) {
   return findElement(dbg, "sourceNode", index)
     .textContent.trim()
     .replace(/^[\s\u200b]*/g, "");
 }
 
 add_task(async function() {
-  const dbg = await initDebugger("doc-sources.html", "simple1", "simple2", "nested-source", "long.js");
+  const dbg = await initDebugger("doc-sources.html");
   const {
     selectors: { getSelectedSource },
     getState
   } = dbg;
 
-  info(`>>> contentTask: evaluate evaled.js\n`)
+  await waitForSources(dbg, "simple1", "simple2", "nested-source", "long.js");
+
+
+  dump(`>>> contentTask: evaluate evaled.js\n`)
   ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
     content.eval("window.evaledFunc = function() {} //# sourceURL=evaled.js");
   });
 
   await waitForSourceCount(dbg, 3);
   // is(getLabel(dbg, 3), "evaled.js", "evaled exists");
   ok(true)
 });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-sources-querystring.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-sources-querystring.js
@@ -5,22 +5,24 @@
 
 function getLabel(dbg, index) {
   return findElement(dbg, "sourceNode", index)
     .textContent.trim()
     .replace(/^[\s\u200b]*/g, "");
 }
 
 add_task(async function() {
-  const dbg = await initDebugger("doc-sources-querystring.html", "simple1.js?x=1", "simple1.js?x=2");
+  const dbg = await initDebugger("doc-sources-querystring.html");
   const {
     selectors: { getSelectedSource },
     getState
   } = dbg;
 
+  await waitForSources(dbg, "simple1.js?x=1", "simple1.js?x=2");
+
   // Expand nodes and make sure more sources appear.
   await assertSourceCount(dbg, 2);
   await clickElement(dbg, "sourceDirectoryLabel", 2);
 
   const labels = [getLabel(dbg, 4), getLabel(dbg, 3)];
   is(
     labels.includes("simple1.js?x=1") && labels.includes("simple1.js?x=2"),
     true,
@@ -33,13 +35,9 @@ add_task(async function() {
   is(tab.innerText, "simple1.js?x=1", "Tab label is simple1.js?x=1");
   await addBreakpoint(dbg, "simple1.js?x=1", 6);
   const breakpointHeading = findElement(dbg, "breakpointItem", 2).innerText;
   is(
     breakpointHeading,
     "simple1.js?x=1",
     "Breakpoint heading is simple1.js?x=1"
   );
-
-  pressKey(dbg, "quickOpen");
-  type(dbg, "simple1.js?x");
-  ok(findElement(dbg, "resultItems")[0].innerText.includes("simple.js?x=1"));
 });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-sources.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-sources.js
@@ -5,22 +5,24 @@
 
 function getLabel(dbg, index) {
   return findElement(dbg, "sourceNode", index)
     .textContent.trim()
     .replace(/^[\s\u200b]*/g, "");
 }
 
 add_task(async function() {
-  const dbg = await initDebugger("doc-sources.html", "simple1", "simple2", "nested-source", "long.js");
+  const dbg = await initDebugger("doc-sources.html");
   const {
     selectors: { getSelectedSource },
     getState
   } = dbg;
 
+  await waitForSources(dbg, "simple1", "simple2", "nested-source", "long.js");
+
   // Expand nodes and make sure more sources appear.
   await assertSourceCount(dbg, 2);
   await clickElement(dbg, "sourceDirectoryLabel", 2);
 
   await assertSourceCount(dbg, 7);
   await clickElement(dbg, "sourceDirectoryLabel", 3);
   await assertSourceCount(dbg, 8);
 
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-tabs-pretty-print.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-tabs-pretty-print.js
@@ -1,24 +1,24 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Tests re-opening pretty printed tabs on load
 
 add_task(async function() {
-  const dbg = await initDebugger("doc-minified.html", "math.min.js");
+  const dbg = await initDebugger("doc-minified.html");
 
   await selectSource(dbg, "math.min.js");
   clickElement(dbg, "prettyPrintButton");
   await waitForSource(dbg, "math.min.js:formatted");
   // Test reloading the debugger
   await waitForSelectedSource(dbg, "math.min.js:formatted");
   await reload(dbg);
 
   await waitForSelectedSource(dbg, "math.min.js:formatted");
   ok(true, "Pretty printed source is selected on reload");
-
+  
   await selectSource(dbg, "math.min.js:formatted");
   const source = findSource(dbg, "math.min.js:formatted");
   dbg.actions.showSource(source.id);
   const focusedTreeElement = findElementWithSelector(dbg, ".sources-list .focused .label");
   is(focusedTreeElement.textContent.trim(), "math.min.js", "Pretty printed source is selected in tree");
 });
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-tabs.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-tabs.js
@@ -3,17 +3,17 @@
 
 // Tests adding and removing tabs
 
 function countTabs(dbg) {
   return findElement(dbg, "sourceTabs").children.length;
 }
 
 add_task(async function() {
-  const dbg = await initDebugger("doc-scripts.html", "simple1", "simple2");
+  const dbg = await initDebugger("doc-scripts.html");
 
   await selectSource(dbg, "simple1");
   await selectSource(dbg, "simple2");
   is(countTabs(dbg), 2);
 
   // Test reloading the debugger
   await reload(dbg, "simple1", "simple2");
   is(countTabs(dbg), 2);
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-toggling-tools.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-toggling-tools.js
@@ -1,17 +1,17 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
 // Tests that you can switch tools, without losing your editor position
 
 add_task(async function() {
-  const dbg = await initDebugger("doc-scripts.html", "long");
+  const dbg = await initDebugger("doc-scripts.html");
 
   await selectSource(dbg, "long");
   getCM(dbg).scrollTo(0, 284);
 
   pressKey(dbg, "inspector");
   pressKey(dbg, "debugger");
 
   is(getCM(dbg).getScrollInfo().top, 284);
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-xhr-breakpoints.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-xhr-breakpoints.js
@@ -41,17 +41,18 @@ function getXHRBreakpointCheckbox(dbg) {
 
 async function clickPauseOnAny(dbg, expectedEvent) {
   getXHRBreakpointCheckbox(dbg).click();
   await waitForDispatch(dbg, expectedEvent);
 }
 
 // Tests that a basic XHR breakpoint works for get and POST is ignored
 add_task(async function() {
-  const dbg = await initDebugger("doc-xhr.html", "fetch.js");
+  const dbg = await initDebugger("doc-xhr.html");
+  await waitForSources(dbg, "fetch.js");
   await dbg.actions.setXHRBreakpoint("doc", "GET");
   invokeInTab("main", "doc-xhr.html");
   await waitForPaused(dbg);
   assertPausedLocation(dbg);
   resume(dbg);
 
   await dbg.actions.removeXHRBreakpoint(0);
   invokeInTab("main", "doc-xhr.html");
@@ -59,17 +60,20 @@ add_task(async function() {
 
   await dbg.actions.setXHRBreakpoint("doc-xhr.html", "POST");
   invokeInTab("main", "doc");
   assertNotPaused(dbg);
 });
 
 // Tests the "pause on any URL" checkbox works properly
 add_task(async function() {
-  const dbg = await initDebugger("doc-xhr.html", "fetch.js");
+  const dbg = await initDebugger("doc-xhr.html");
+  await waitForSources(dbg, "fetch.js");
+
+  info("HERE 1");
 
   // Enable pause on any URL
   await clickPauseOnAny(dbg, "SET_XHR_BREAKPOINT");
 
   invokeInTab("main", "doc-xhr.html");
   await waitForPaused(dbg);
   await resume(dbg);
 
@@ -78,16 +82,17 @@ add_task(async function() {
   await resume(dbg);
 
   invokeInTab("main", "README.md");
   await waitForPaused(dbg);
   await resume(dbg);
 
   // Disable pause on any URL
   await clickPauseOnAny(dbg, "DISABLE_XHR_BREAKPOINT");
+  info("HERE 4");
   invokeInTab("main", "README.md");
   assertNotPaused(dbg);
 
   // Turn off the checkbox
   await dbg.actions.removeXHRBreakpoint(0);
 });
 
 // Tests removal works properly
@@ -103,18 +108,18 @@ add_task(async function() {
   await addXHRBreakpoint(dbg, "4");
 
   // Remove "2"
   await removeXHRBreakpoint(dbg, 1);
 
   const listItems = getXHRBreakpointsElements(dbg);
   is(listItems.length, 3, "3 XHR breakpoints display in list");
   is(
-    pauseOnAnyCheckbox.checked, true,
+    pauseOnAnyCheckbox.checked, true, 
     "The pause on any is still checked"
   );
   is(
     getXHRBreakpointLabels(listItems).join(""),
     "134",
     "Only the desired breakpoint was removed"
   );
 
-});
+});
\ No newline at end of file
--- a/devtools/client/debugger/new/test/mochitest/helpers.js
+++ b/devtools/client/debugger/new/test/mochitest/helpers.js
@@ -491,22 +491,20 @@ function clearDebuggerPreferences() {
 /**
  * Intilializes the debugger.
  *
  * @memberof mochitest
  * @param {String} url
  * @return {Promise} dbg
  * @static
  */
-async function initDebugger(url, ...sources) {
+async function initDebugger(url) {
   clearDebuggerPreferences();
   const toolbox = await openNewTabAndToolbox(EXAMPLE_URL + url, "jsdebugger");
-  const dbg = createDebuggerContext(toolbox);
-  await waitForSources(dbg, ...sources)
-  return dbg;
+  return createDebuggerContext(toolbox);
 }
 
 async function initPane(url, pane) {
   clearDebuggerPreferences();
   return openNewTabAndToolbox(EXAMPLE_URL + url, pane);
 }
 
 window.resumeTest = undefined;
@@ -1025,37 +1023,23 @@ const selectors = {
     `.expressions-list .expression-container:nth-child(${i}) .object-delimiter + *`,
   expressionClose: i =>
     `.expressions-list .expression-container:nth-child(${i}) .close`,
   expressionInput: ".expressions-list  input.input-expression",
   expressionNodes: ".expressions-list .tree-node",
   scopesHeader: ".scopes-pane ._header",
   breakpointItem: i => `.breakpoints-list div:nth-of-type(${i})`,
   breakpointItems: `.breakpoints-list .breakpoint`,
-  breakpointContextMenu: {
-    disableSelf: "#node-menu-disable-self",
-    disableAll: "#node-menu-disable-all",
-    disableOthers: "#node-menu-disable-others",
-    enableSelf: "#node-menu-enable-self",
-    enableOthers: "#node-menu-enable-others",
-    remove: "#node-menu-delete-self",
-    removeOthers: "#node-menu-delete-other",
-    removeCondition: "#node-menu-remove-condition"
-  },
   scopes: ".scopes-list",
   scopeNode: i => `.scopes-list .tree-node:nth-child(${i}) .object-label`,
   scopeValue: i =>
     `.scopes-list .tree-node:nth-child(${i}) .object-delimiter + *`,
   frame: i => `.frames ul li:nth-child(${i})`,
   frames: ".frames ul li",
   gutter: i => `.CodeMirror-code *:nth-child(${i}) .CodeMirror-linenumber`,
-  gutterContextMenu: {
-    addConditionalBreakpoint: "#node-menu-add-conditional-breakpoint",
-    editBreakpoint: "#node-menu-edit-conditional-breakpoint"
-  },
   menuitem: i => `menupopup menuitem:nth-child(${i})`,
   pauseOnExceptions: ".pause-exceptions",
   breakpoint: ".CodeMirror-code > .new-breakpoint",
   highlightLine: ".CodeMirror-code > .highlight-line",
   debugLine: ".new-debug-line",
   debugErrorLine: ".new-debug-line-error",
   codeMirror: ".CodeMirror",
   resume: ".resume.active",
@@ -1156,24 +1140,24 @@ function rightClickElement(dbg, elementN
   const doc = dbg.win.document;
   return EventUtils.synthesizeMouseAtCenter(
     doc.querySelector(selector),
     { type: "contextmenu" },
     dbg.win
   );
 }
 
-function selectContextMenuItem(dbg, selector) {
+function selectMenuItem(dbg, index) {
   // the context menu is in the toolbox window
   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 item = popup.querySelector(selector);
+  const item = popup.querySelector(`menuitem:nth-child(${index})`);
   return EventUtils.synthesizeMouseAtCenter(item, {}, dbg.toolbox.win);
 }
 
 /**
  * Toggles the debugger call stack accordian.
  *
  * @memberof mochitest/actions
  * @param {Object} dbg
--- a/devtools/client/locales/en-US/debugger.properties
+++ b/devtools/client/locales/en-US/debugger.properties
@@ -593,20 +593,16 @@ sourceFooter.mappedSourceTooltip=(Source
 # LOCALIZATION NOTE (sourceFooter.mappedSuffix): Text associated
 # with a mapped source.  Displays next to URLs in tree and tabs.
 sourceFooter.mappedSuffix=(mapped)
 
 # LOCALIZATION NOTE (sourceFooter.codeCoverage): Text associated
 # with a code coverage button
 sourceFooter.codeCoverage=Code coverage
 
-# LOCALIZATION NOTE (sourceFooter.currentCursorPosition): Text associated
-# with the current cursor line and column
-sourceFooter.currentCursorPosition=(%S, %S)
-
 # LOCALIZATION NOTE (sourceTabs.closeTabButtonTooltip): The tooltip that is displayed
 # for close tab button in source tabs.
 sourceTabs.closeTabButtonTooltip=Close tab
 
 # LOCALIZATION NOTE (scopes.header): Scopes right sidebar pane header.
 scopes.header=Scopes
 
 # LOCALIZATION NOTE (scopes.notAvailable): Scopes right sidebar pane message
--- a/devtools/client/preferences/debugger.js
+++ b/devtools/client/preferences/debugger.js
@@ -42,27 +42,27 @@ pref("devtools.debugger.tabsBlackBoxed",
 pref("devtools.debugger.pending-selected-location", "{}");
 pref("devtools.debugger.pending-breakpoints", "{}");
 pref("devtools.debugger.expressions", "[]");
 pref("devtools.debugger.file-search-case-sensitive", false);
 pref("devtools.debugger.file-search-whole-word", false);
 pref("devtools.debugger.file-search-regex-match", false);
 pref("devtools.debugger.project-directory-root", "");
 pref("devtools.debugger.skip-pausing", false);
-pref("devtools.debugger.logging", false);
 
 pref("devtools.debugger.features.wasm", true);
 pref("devtools.debugger.features.shortcuts", true);
 pref("devtools.debugger.features.root", true);
 pref("devtools.debugger.features.column-breakpoints", false);
 pref("devtools.debugger.features.chrome-scopes", false);
 pref("devtools.debugger.features.map-scopes", true);
 pref("devtools.debugger.features.remove-command-bar-options", false);
 pref("devtools.debugger.features.workers", true);
 pref("devtools.debugger.features.code-coverage", false);
+pref("devtools.debugger.features.event-listeners", false);
 pref("devtools.debugger.features.code-folding", false);
 pref("devtools.debugger.features.outline", true);
 pref("devtools.debugger.features.pause-points", true);
 pref("devtools.debugger.features.component-pane", false);
 pref("devtools.debugger.features.async-stepping", true);
 pref("devtools.debugger.features.skip-pausing", true);
 pref("devtools.debugger.features.autocomplete-expressions", false);
 pref("devtools.debugger.features.map-expression-bindings", true);
--- a/devtools/client/shared/components/reps/reps.js
+++ b/devtools/client/shared/components/reps/reps.js
@@ -6191,24 +6191,450 @@ module.exports = {
 
 "use strict";
 
 
 /* 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/>. */
 
-const ObjectInspector = __webpack_require__(3829);
+const ObjectInspector = __webpack_require__(3696);
 const utils = __webpack_require__(3657);
 const reducer = __webpack_require__(3703);
 
 module.exports = { ObjectInspector, utils, reducer };
 
 /***/ }),
 
+/***/ 3696:
+/***/ (function(module, exports, __webpack_require__) {
+
+"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; };
+
+var _devtoolsServices = __webpack_require__(22);
+
+var _devtoolsServices2 = _interopRequireDefault(_devtoolsServices);
+
+var _devtoolsComponents = __webpack_require__(3669);
+
+var _devtoolsComponents2 = _interopRequireDefault(_devtoolsComponents);
+
+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/>. */
+
+const { Component, createFactory, createElement } = __webpack_require__(0);
+const dom = __webpack_require__(3643);
+const { connect } = __webpack_require__(3592);
+const actions = __webpack_require__(3699);
+
+const selectors = __webpack_require__(3703);
+
+const { appinfo } = _devtoolsServices2.default;
+const isMacOS = appinfo.OS === "Darwin";
+
+const Tree = createFactory(_devtoolsComponents2.default.Tree);
+__webpack_require__(3697);
+
+const classnames = __webpack_require__(175);
+const { MODE } = __webpack_require__(3645);
+
+const Utils = __webpack_require__(3657);
+const { renderRep, shouldRenderRootsInReps } = Utils;
+
+const {
+  getChildren,
+  getActor,
+  getParent,
+  getValue,
+  nodeHasAccessors,
+  nodeHasProperties,
+  nodeIsBlock,
+  nodeIsDefaultProperties,
+  nodeIsFunction,
+  nodeIsGetter,
+  nodeIsMapEntry,
+  nodeIsMissingArguments,
+  nodeIsOptimizedOut,
+  nodeIsPrimitive,
+  nodeIsPrototype,
+  nodeIsSetter,
+  nodeIsUninitializedBinding,
+  nodeIsUnmappedBinding,
+  nodeIsUnscopedBinding,
+  nodeIsWindow,
+  nodeIsLongString,
+  nodeHasFullText
+} = Utils.node;
+
+// This implements a component that renders an interactive inspector
+// for looking at JavaScript objects. It expects descriptions of
+// objects from the protocol, and will dynamically fetch children
+// properties as objects are expanded.
+//
+// If you want to inspect a single object, pass the name and the
+// protocol descriptor of it:
+//
+//  ObjectInspector({
+//    name: "foo",
+//    desc: { writable: true, ..., { value: { actor: "1", ... }}},
+//    ...
+//  })
+//
+// If you want multiple top-level objects (like scopes), you can pass
+// an array of manually constructed nodes as `roots`:
+//
+//  ObjectInspector({
+//    roots: [{ name: ... }, ...],
+//    ...
+//  });
+
+// There are 3 types of nodes: a simple node with a children array, an
+// object that has properties that should be children when they are
+// fetched, and a primitive value that should be displayed with no
+// children.
+
+class ObjectInspector extends Component {
+  constructor(props) {
+    super();
+    this.cachedNodes = new Map();
+
+    const self = this;
+
+    self.getItemChildren = this.getItemChildren.bind(this);
+    self.renderTreeItem = this.renderTreeItem.bind(this);
+    self.setExpanded = this.setExpanded.bind(this);
+    self.focusItem = this.focusItem.bind(this);
+    self.getRoots = this.getRoots.bind(this);
+  }
+
+  componentWillMount() {
+    this.roots = this.props.roots;
+    this.focusedItem = this.props.focusedItem;
+  }
+
+  componentWillUpdate(nextProps) {
+    if (this.roots !== nextProps.roots) {
+      // Since the roots changed, we assume the properties did as well,
+      // so we need to cleanup the component internal state.
+
+      // We can clear the cachedNodes to avoid bugs and memory leaks.
+      this.cachedNodes.clear();
+      this.roots = nextProps.roots;
+      this.focusedItem = nextProps.focusedItem;
+      if (this.props.rootsChanged) {
+        this.props.rootsChanged();
+      }
+    }
+  }
+
+  shouldComponentUpdate(nextProps) {
+    const { expandedPaths, loadedProperties } = this.props;
+
+    // We should update if:
+    // - there are new loaded properties
+    // - OR the expanded paths number changed, and all of them have properties
+    //      loaded
+    // - OR the expanded paths number did not changed, but old and new sets
+    //      differ
+    // - OR the focused node changed.
+    return loadedProperties.size !== nextProps.loadedProperties.size || expandedPaths.size !== nextProps.expandedPaths.size && [...nextProps.expandedPaths].every(path => nextProps.loadedProperties.has(path)) || expandedPaths.size === nextProps.expandedPaths.size && [...nextProps.expandedPaths].some(key => !expandedPaths.has(key)) || this.focusedItem !== nextProps.focusedItem || this.roots !== nextProps.roots;
+  }
+
+  componentWillUnmount() {
+    this.props.closeObjectInspector();
+  }
+
+  getItemChildren(item) {
+    const { loadedProperties } = this.props;
+    const { cachedNodes } = this;
+
+    return getChildren({
+      loadedProperties,
+      cachedNodes,
+      item
+    });
+  }
+
+  getRoots() {
+    return this.props.roots;
+  }
+
+  getNodeKey(item) {
+    return item.path && typeof item.path.toString === "function" ? item.path.toString() : JSON.stringify(item);
+  }
+
+  setExpanded(item, expand) {
+    if (nodeIsPrimitive(item)) {
+      return;
+    }
+
+    const {
+      nodeExpand,
+      nodeCollapse,
+      recordTelemetryEvent,
+      roots
+    } = this.props;
+
+    if (expand === true) {
+      const actor = getActor(item, roots);
+      nodeExpand(item, actor);
+      if (recordTelemetryEvent) {
+        recordTelemetryEvent("object_expanded");
+      }
+    } else {
+      nodeCollapse(item);
+    }
+  }
+
+  focusItem(item) {
+    const { focusable = true, onFocus } = this.props;
+
+    if (focusable && this.focusedItem !== item) {
+      this.focusedItem = item;
+      this.forceUpdate();
+
+      if (onFocus) {
+        onFocus(item);
+      }
+    }
+  }
+
+  // eslint-disable-next-line complexity
+  getTreeItemLabelAndValue(item, depth, expanded) {
+    const label = item.name;
+    const isPrimitive = nodeIsPrimitive(item);
+
+    if (nodeIsOptimizedOut(item)) {
+      return {
+        label,
+        value: dom.span({ className: "unavailable" }, "(optimized away)")
+      };
+    }
+
+    if (nodeIsUninitializedBinding(item)) {
+      return {
+        label,
+        value: dom.span({ className: "unavailable" }, "(uninitialized)")
+      };
+    }
+
+    if (nodeIsUnmappedBinding(item)) {
+      return {
+        label,
+        value: dom.span({ className: "unavailable" }, "(unmapped)")
+      };
+    }
+
+    if (nodeIsUnscopedBinding(item)) {
+      return {
+        label,
+        value: dom.span({ className: "unavailable" }, "(unscoped)")
+      };
+    }
+
+    const itemValue = getValue(item);
+    const unavailable = isPrimitive && itemValue && itemValue.hasOwnProperty && itemValue.hasOwnProperty("unavailable");
+
+    if (nodeIsMissingArguments(item) || unavailable) {
+      return {
+        label,
+        value: dom.span({ className: "unavailable" }, "(unavailable)")
+      };
+    }
+
+    if (nodeIsFunction(item) && !nodeIsGetter(item) && !nodeIsSetter(item) && (this.props.mode === MODE.TINY || !this.props.mode)) {
+      return {
+        label: Utils.renderRep(item, _extends({}, this.props, {
+          functionName: label
+        }))
+      };
+    }
+
+    if (nodeHasProperties(item) || nodeHasAccessors(item) || nodeIsMapEntry(item) || nodeIsLongString(item) || isPrimitive) {
+      const repProps = _extends({}, this.props);
+      if (depth > 0) {
+        repProps.mode = this.props.mode === MODE.LONG ? MODE.SHORT : MODE.TINY;
+      }
+      if (expanded) {
+        repProps.mode = MODE.TINY;
+      }
+
+      if (nodeIsLongString(item)) {
+        repProps.member = {
+          open: nodeHasFullText(item) && expanded
+        };
+      }
+
+      return {
+        label,
+        value: Utils.renderRep(item, repProps)
+      };
+    }
+
+    return {
+      label
+    };
+  }
+
+  renderTreeItemLabel(label, item, depth, focused, expanded) {
+    if (label === null || typeof label === "undefined") {
+      return null;
+    }
+
+    const { onLabelClick } = this.props;
+
+    return dom.span({
+      className: "object-label",
+      onClick: onLabelClick ? event => {
+        event.stopPropagation();
+
+        // If the user selected text, bail out.
+        if (Utils.selection.documentHasSelection()) {
+          return;
+        }
+
+        onLabelClick(item, {
+          depth,
+          focused,
+          expanded,
+          setExpanded: this.setExpanded
+        });
+      } : undefined
+    }, label);
+  }
+
+  getTreeTopElementProps(item, depth, focused, expanded) {
+    const { onCmdCtrlClick, onDoubleClick, dimTopLevelWindow } = this.props;
+
+    const parentElementProps = {
+      className: classnames("node object-node", {
+        focused,
+        lessen: !expanded && (nodeIsDefaultProperties(item) || nodeIsPrototype(item) || nodeIsGetter(item) || nodeIsSetter(item) || dimTopLevelWindow === true && nodeIsWindow(item) && depth === 0),
+        block: nodeIsBlock(item)
+      }),
+      onClick: e => {
+        if (onCmdCtrlClick && (isMacOS && e.metaKey || !isMacOS && e.ctrlKey)) {
+          onCmdCtrlClick(item, {
+            depth,
+            event: e,
+            focused,
+            expanded
+          });
+          e.stopPropagation();
+          return;
+        }
+
+        // If this click happened because the user selected some text, bail out.
+        // Note that if the user selected some text before and then clicks here,
+        // the previously selected text will be first unselected, unless the
+        // user clicked on the arrow itself. Indeed because the arrow is an
+        // image, clicking on it does not remove any existing text selection.
+        // So we need to also check if the arrow was clicked.
+        if (Utils.selection.documentHasSelection() && !(e.target && e.target.matches && e.target.matches(".arrow"))) {
+          e.stopPropagation();
+        }
+      }
+    };
+
+    if (onDoubleClick) {
+      parentElementProps.onDoubleClick = e => {
+        e.stopPropagation();
+        onDoubleClick(item, {
+          depth,
+          focused,
+          expanded
+        });
+      };
+    }
+
+    return parentElementProps;
+  }
+
+  renderTreeItem(item, depth, focused, arrow, expanded) {
+    const { label, value } = this.getTreeItemLabelAndValue(item, depth, expanded);
+    const labelElement = this.renderTreeItemLabel(label, item, depth, focused, expanded);
+    const delimiter = value && labelElement ? dom.span({ className: "object-delimiter" }, ": ") : null;
+
+    return dom.div(this.getTreeTopElementProps(item, depth, focused, expanded), arrow, labelElement, delimiter, value);
+  }
+
+  render() {
+    const {
+      autoExpandAll = true,
+      autoExpandDepth = 1,
+      focusable = true,
+      disableWrap = false,
+      expandedPaths,
+      inline
+    } = this.props;
+
+    return Tree({
+      className: classnames({
+        inline,
+        nowrap: disableWrap,
+        "object-inspector": true
+      }),
+
+      autoExpandAll,
+      autoExpandDepth,
+
+      isExpanded: item => expandedPaths && expandedPaths.has(item.path),
+      // TODO: We don't want property with getters to be expandable until we
+      // do have a mechanism to invoke the getter (See #6140).
+      isExpandable: item => !nodeIsPrimitive(item) && !nodeHasAccessors(item),
+      focused: this.focusedItem,
+
+      getRoots: this.getRoots,
+      getParent,
+      getChildren: this.getItemChildren,
+      getKey: this.getNodeKey,
+
+      onExpand: item => this.setExpanded(item, true),
+      onCollapse: item => this.setExpanded(item, false),
+      onFocus: focusable ? this.focusItem : null,
+
+      renderItem: this.renderTreeItem
+    });
+  }
+}
+
+function mapStateToProps(state, props) {
+  return {
+    actors: selectors.getActors(state),
+    expandedPaths: selectors.getExpandedPaths(state),
+    loadedProperties: selectors.getLoadedProperties(state)
+  };
+}
+
+const OI = connect(mapStateToProps, actions)(ObjectInspector);
+
+module.exports = props => {
+  const { roots } = props;
+  if (shouldRenderRootsInReps(roots)) {
+    return renderRep(roots[0], props);
+  }
+
+  return createElement(OI, props);
+};
+
+/***/ }),
+
+/***/ 3697:
+/***/ (function(module, exports) {
+
+// removed by extract-text-webpack-plugin
+
+/***/ }),
+
 /***/ 3698:
 /***/ (function(module, exports, __webpack_require__) {
 
 "use strict";
 
 
 /* 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
@@ -6544,487 +6970,12 @@ function supportsObject(object, noGrip =
 }
 
 // Exports from this module
 module.exports = {
   rep: wrapRender(Accessible),
   supportsObject
 };
 
-/***/ }),
-
-/***/ 3829:
-/***/ (function(module, exports, __webpack_require__) {
-
-"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; };
-
-var _devtoolsComponents = __webpack_require__(3669);
-
-var _devtoolsComponents2 = _interopRequireDefault(_devtoolsComponents);
-
-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/>. */
-
-const { Component, createFactory, createElement } = __webpack_require__(0);
-const { connect } = __webpack_require__(3592);
-const actions = __webpack_require__(3699);
-
-const selectors = __webpack_require__(3703);
-
-const Tree = createFactory(_devtoolsComponents2.default.Tree);
-__webpack_require__(3830);
-
-const ObjectInspectorItem = createFactory(__webpack_require__(3831));
-
-const classnames = __webpack_require__(175);
-
-const Utils = __webpack_require__(3657);
-const { renderRep, shouldRenderRootsInReps } = Utils;
-const {
-  getChildren,
-  getActor,
-  getParent,
-  nodeHasAccessors,
-  nodeIsPrimitive
-} = Utils.node;
-
-// This implements a component that renders an interactive inspector
-// for looking at JavaScript objects. It expects descriptions of
-// objects from the protocol, and will dynamically fetch children
-// properties as objects are expanded.
-//
-// If you want to inspect a single object, pass the name and the
-// protocol descriptor of it:
-//
-//  ObjectInspector({
-//    name: "foo",
-//    desc: { writable: true, ..., { value: { actor: "1", ... }}},
-//    ...
-//  })
-//
-// If you want multiple top-level objects (like scopes), you can pass
-// an array of manually constructed nodes as `roots`:
-//
-//  ObjectInspector({
-//    roots: [{ name: ... }, ...],
-//    ...
-//  });
-
-// There are 3 types of nodes: a simple node with a children array, an
-// object that has properties that should be children when they are
-// fetched, and a primitive value that should be displayed with no
-// children.
-
-class ObjectInspector extends Component {
-  constructor(props) {
-    super();
-    this.cachedNodes = new Map();
-
-    const self = this;
-
-    self.getItemChildren = this.getItemChildren.bind(this);
-    self.setExpanded = this.setExpanded.bind(this);
-    self.focusItem = this.focusItem.bind(this);
-    self.getRoots = this.getRoots.bind(this);
-  }
-
-  componentWillMount() {
-    this.roots = this.props.roots;
-    this.focusedItem = this.props.focusedItem;
-  }
-
-  componentWillUpdate(nextProps) {
-    if (this.roots !== nextProps.roots) {
-      // Since the roots changed, we assume the properties did as well,
-      // so we need to cleanup the component internal state.
-
-      // We can clear the cachedNodes to avoid bugs and memory leaks.
-      this.cachedNodes.clear();
-      this.roots = nextProps.roots;
-      this.focusedItem = nextProps.focusedItem;
-      if (this.props.rootsChanged) {
-        this.props.rootsChanged();
-      }
-    }
-  }
-
-  shouldComponentUpdate(nextProps) {
-    const { expandedPaths, loadedProperties } = this.props;
-
-    // We should update if:
-    // - there are new loaded properties
-    // - OR the expanded paths number changed, and all of them have properties
-    //      loaded
-    // - OR the expanded paths number did not changed, but old and new sets
-    //      differ
-    // - OR the focused node changed.
-    return loadedProperties.size !== nextProps.loadedProperties.size || expandedPaths.size !== nextProps.expandedPaths.size && [...nextProps.expandedPaths].every(path => nextProps.loadedProperties.has(path)) || expandedPaths.size === nextProps.expandedPaths.size && [...nextProps.expandedPaths].some(key => !expandedPaths.has(key)) || this.focusedItem !== nextProps.focusedItem || this.roots !== nextProps.roots;
-  }
-
-  componentWillUnmount() {
-    this.props.closeObjectInspector();
-  }
-
-  getItemChildren(item) {
-    const { loadedProperties } = this.props;
-    const { cachedNodes } = this;
-
-    return getChildren({
-      loadedProperties,
-      cachedNodes,
-      item
-    });
-  }
-
-  getRoots() {
-    return this.props.roots;
-  }
-
-  getNodeKey(item) {
-    return item.path && typeof item.path.toString === "function" ? item.path.toString() : JSON.stringify(item);
-  }
-
-  setExpanded(item, expand) {
-    if (nodeIsPrimitive(item)) {
-      return;
-    }
-
-    const {
-      nodeExpand,
-      nodeCollapse,
-      recordTelemetryEvent,
-      roots
-    } = this.props;
-
-    if (expand === true) {
-      const actor = getActor(item, roots);
-      nodeExpand(item, actor);
-      if (recordTelemetryEvent) {
-        recordTelemetryEvent("object_expanded");
-      }
-    } else {
-      nodeCollapse(item);
-    }
-  }
-
-  focusItem(item) {
-    const { focusable = true, onFocus } = this.props;
-
-    if (focusable && this.focusedItem !== item) {
-      this.focusedItem = item;
-      this.forceUpdate();
-
-      if (onFocus) {
-        onFocus(item);
-      }
-    }
-  }
-
-  render() {
-    const {
-      autoExpandAll = true,
-      autoExpandDepth = 1,
-      focusable = true,
-      disableWrap = false,
-      expandedPaths,
-      inline
-    } = this.props;
-
-    return Tree({
-      className: classnames({
-        inline,
-        nowrap: disableWrap,
-        "object-inspector": true
-      }),
-
-      autoExpandAll,
-      autoExpandDepth,
-
-      isExpanded: item => expandedPaths && expandedPaths.has(item.path),
-      // TODO: We don't want property with getters to be expandable until we
-      // do have a mechanism to invoke the getter (See #6140).
-      isExpandable: item => !nodeIsPrimitive(item) && !nodeHasAccessors(item),
-      focused: this.focusedItem,
-
-      getRoots: this.getRoots,
-      getParent,
-      getChildren: this.getItemChildren,
-      getKey: this.getNodeKey,
-
-      onExpand: item => this.setExpanded(item, true),
-      onCollapse: item => this.setExpanded(item, false),
-      onFocus: focusable ? this.focusItem : null,
-
-      renderItem: (item, depth, focused, arrow, expanded) => ObjectInspectorItem(_extends({
-        item,
-        depth,
-        focused,
-        arrow,
-        expanded
-      }, this.props, {
-        setExpanded: this.setExpanded
-      }))
-    });
-  }
-}
-
-function mapStateToProps(state, props) {
-  return {
-    expandedPaths: selectors.getExpandedPaths(state),
-    loadedProperties: selectors.getLoadedProperties(state)
-  };
-}
-
-const OI = connect(mapStateToProps, actions)(ObjectInspector);
-
-module.exports = props => {
-  const { roots } = props;
-  if (shouldRenderRootsInReps(roots)) {
-    return renderRep(roots[0], props);
-  }
-
-  return createElement(OI, props);
-};
-
-/***/ }),
-
-/***/ 3830:
-/***/ (function(module, exports) {
-
-// removed by extract-text-webpack-plugin
-
-/***/ }),
-
-/***/ 3831:
-/***/ (function(module, exports, __webpack_require__) {
-
-"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; };
-
-var _devtoolsServices = __webpack_require__(22);
-
-var _devtoolsServices2 = _interopRequireDefault(_devtoolsServices);
-
-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/>. */
-
-const { Component } = __webpack_require__(0);
-const dom = __webpack_require__(3643);
-
-const { appinfo } = _devtoolsServices2.default;
-const isMacOS = appinfo.OS === "Darwin";
-
-const classnames = __webpack_require__(175);
-const { MODE } = __webpack_require__(3645);
-
-const Utils = __webpack_require__(3657);
-
-const {
-  getValue,
-  nodeHasAccessors,
-  nodeHasProperties,
-  nodeIsBlock,
-  nodeIsDefaultProperties,
-  nodeIsFunction,
-  nodeIsGetter,
-  nodeIsMapEntry,
-  nodeIsMissingArguments,
-  nodeIsOptimizedOut,
-  nodeIsPrimitive,
-  nodeIsPrototype,
-  nodeIsSetter,
-  nodeIsUninitializedBinding,
-  nodeIsUnmappedBinding,
-  nodeIsUnscopedBinding,
-  nodeIsWindow,
-  nodeIsLongString,
-  nodeHasFullText
-} = Utils.node;
-
-class ObjectInspectorItem extends Component {
-  // eslint-disable-next-line complexity
-  getLabelAndValue() {
-    const { item, depth, expanded, mode } = this.props;
-
-    const label = item.name;
-    const isPrimitive = nodeIsPrimitive(item);
-
-    if (nodeIsOptimizedOut(item)) {
-      return {
-        label,
-        value: dom.span({ className: "unavailable" }, "(optimized away)")
-      };
-    }
-
-    if (nodeIsUninitializedBinding(item)) {
-      return {
-        label,
-        value: dom.span({ className: "unavailable" }, "(uninitialized)")
-      };
-    }
-
-    if (nodeIsUnmappedBinding(item)) {
-      return {
-        label,
-        value: dom.span({ className: "unavailable" }, "(unmapped)")
-      };
-    }
-
-    if (nodeIsUnscopedBinding(item)) {
-      return {
-        label,
-        value: dom.span({ className: "unavailable" }, "(unscoped)")
-      };
-    }
-
-    const itemValue = getValue(item);
-    const unavailable = isPrimitive && itemValue && itemValue.hasOwnProperty && itemValue.hasOwnProperty("unavailable");
-
-    if (nodeIsMissingArguments(item) || unavailable) {
-      return {
-        label,
-        value: dom.span({ className: "unavailable" }, "(unavailable)")
-      };
-    }
-
-    if (nodeIsFunction(item) && !nodeIsGetter(item) && !nodeIsSetter(item) && (mode === MODE.TINY || !mode)) {
-      return {
-        label: Utils.renderRep(item, _extends({}, this.props, {
-          functionName: label
-        }))
-      };
-    }
-
-    if (nodeHasProperties(item) || nodeHasAccessors(item) || nodeIsMapEntry(item) || nodeIsLongString(item) || isPrimitive) {
-      const repProps = _extends({}, this.props);
-      if (depth > 0) {
-        repProps.mode = mode === MODE.LONG ? MODE.SHORT : MODE.TINY;
-      }
-      if (expanded) {
-        repProps.mode = MODE.TINY;
-      }
-
-      if (nodeIsLongString(item)) {
-        repProps.member = {
-          open: nodeHasFullText(item) && expanded
-        };
-      }
-
-      return {
-        label,
-        value: Utils.renderRep(item, repProps)
-      };
-    }
-
-    return {
-      label
-    };
-  }
-
-  getTreeItemProps() {
-    const {
-      item,
-      depth,
-      focused,
-      expanded,
-      onCmdCtrlClick,
-      onDoubleClick,
-      dimTopLevelWindow
-    } = this.props;
-
-    const parentElementProps = {
-      className: classnames("node object-node", {
-        focused,
-        lessen: !expanded && (nodeIsDefaultProperties(item) || nodeIsPrototype(item) || nodeIsGetter(item) || nodeIsSetter(item) || dimTopLevelWindow === true && nodeIsWindow(item) && depth === 0),
-        block: nodeIsBlock(item)
-      }),
-      onClick: e => {
-        if (onCmdCtrlClick && (isMacOS && e.metaKey || !isMacOS && e.ctrlKey)) {
-          onCmdCtrlClick(item, {
-            depth,
-            event: e,
-            focused,
-            expanded
-          });
-          e.stopPropagation();
-          return;
-        }
-
-        // If this click happened because the user selected some text, bail out.
-        // Note that if the user selected some text before and then clicks here,
-        // the previously selected text will be first unselected, unless the
-        // user clicked on the arrow itself. Indeed because the arrow is an
-        // image, clicking on it does not remove any existing text selection.
-        // So we need to also check if the arrow was clicked.
-        if (Utils.selection.documentHasSelection() && !(e.target && e.target.matches && e.target.matches(".arrow"))) {
-          e.stopPropagation();
-        }
-      }
-    };
-
-    if (onDoubleClick) {
-      parentElementProps.onDoubleClick = e => {
-        e.stopPropagation();
-        onDoubleClick(item, {
-          depth,
-          focused,
-          expanded
-        });
-      };
-    }
-
-    return parentElementProps;
-  }
-
-  renderLabel(label) {
-    if (label === null || typeof label === "undefined") {
-      return null;
-    }
-
-    const { item, depth, focused, expanded, onLabelClick } = this.props;
-    return dom.span({
-      className: "object-label",
-      onClick: onLabelClick ? event => {
-        event.stopPropagation();
-
-        // If the user selected text, bail out.
-        if (Utils.selection.documentHasSelection()) {
-          return;
-        }
-
-        onLabelClick(item, {
-          depth,
-          focused,
-          expanded,
-          setExpanded: this.props.setExpanded
-        });
-      } : undefined
-    }, label);
-  }
-
-  render() {
-    const { arrow } = this.props;
-
-    const { label, value } = this.getLabelAndValue();
-    const labelElement = this.renderLabel(label);
-    const delimiter = value && labelElement ? dom.span({ className: "object-delimiter" }, ": ") : null;
-
-    return dom.div(this.getTreeItemProps(), arrow, labelElement, delimiter, value);
-  }
-}
-
-module.exports = ObjectInspectorItem;
-
 /***/ })
 
 /******/ });
 });
\ No newline at end of file