Bug 1536216 - Redesign map scopes pane r=jlast
authorDavid Walsh <davidwalsh83@gmail.com>
Tue, 19 Mar 2019 17:03:13 +0000
changeset 465056 1ca9ba8d1647a4b8f255167c021d09fa012bfbf5
parent 465055 117ee5068079863807c27cdb6b7e63c412f7bdb7
child 465057 85bd45178007470651a23a54a416ac9208b1d531
push id35730
push userrmaries@mozilla.com
push dateTue, 19 Mar 2019 21:51:47 +0000
treeherdermozilla-central@4f6d8ed9e948 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjlast
bugs1536216
milestone68.0a1
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
Bug 1536216 - Redesign map scopes pane r=jlast Adds a checkbox to the Scopes accordion header to allow mapping scope. Differential Revision: https://phabricator.services.mozilla.com/D24059
devtools/client/debugger/new/dist/debugger.css
devtools/client/debugger/new/src/components/SecondaryPanes/Scopes.css
devtools/client/debugger/new/src/components/SecondaryPanes/Scopes.js
devtools/client/debugger/new/src/components/SecondaryPanes/index.js
devtools/client/locales/en-US/debugger.properties
--- a/devtools/client/debugger/new/dist/debugger.css
+++ b/devtools/client/debugger/new/dist/debugger.css
@@ -4021,50 +4021,35 @@ html[dir="rtl"] .event-listeners-content
 	margin-inline-start: 0px;
 	margin-top: 0px;
 	margin-bottom: 0px;
 }
 /* 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/>. */
 
-.scopes-content .toggle-map-scopes {
-  border-bottom: 1px solid var(--theme-splitter-color);
-  margin-bottom: 3px;
-  margin-left: 10px;
-  padding: 0.5em 0;
-}
-
-.scopes-content .toggle-map-scopes input {
-  padding-inline-start: 2px;
-  margin-inline-start: 0;
-  vertical-align: text-bottom;
-}
-
-.scopes-content .toggle-map-scopes-label {
-  padding-inline-start: 2px;
-  padding-inline-end: 8px;
-  cursor: default;
-  flex-grow: 1;
-  -moz-user-select: none;
+ .secondary-panes .map-scopes-header {
+  padding-inline-end: 3px;
+ }
+
+.secondary-panes .header-buttons .img.shortcuts {
+  width: 14px;
+  height: 14px;
+  /* Better vertical centering of the icon */
+  margin-top: -2px;
 }
 
 .scopes-content .toggle-map-scopes a.mdn {
-  padding-inline-end: 10px;
+  padding-inline-start: 3px;
 }
 
 .scopes-content .toggle-map-scopes .img.shortcuts {
   background: var(--theme-comment);
 }
 
-.scopes-content .toggle-map-scopes {
-  display: flex;
-  align-items: center;
-}
-
 .object-node.default-property {
   opacity: 0.6;
 }
 
 .object-node {
   padding-left: 4px;
 }
 
--- a/devtools/client/debugger/new/src/components/SecondaryPanes/Scopes.css
+++ b/devtools/client/debugger/new/src/components/SecondaryPanes/Scopes.css
@@ -1,46 +1,31 @@
 /* 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/>. */
 
-.scopes-content .toggle-map-scopes {
-  border-bottom: 1px solid var(--theme-splitter-color);
-  margin-bottom: 3px;
-  margin-left: 10px;
-  padding: 0.5em 0;
-}
+ .secondary-panes .map-scopes-header {
+  padding-inline-end: 3px;
+ }
 
-.scopes-content .toggle-map-scopes input {
-  padding-inline-start: 2px;
-  margin-inline-start: 0;
-  vertical-align: text-bottom;
-}
-
-.scopes-content .toggle-map-scopes-label {
-  padding-inline-start: 2px;
-  padding-inline-end: 8px;
-  cursor: default;
-  flex-grow: 1;
-  -moz-user-select: none;
+.secondary-panes .header-buttons .img.shortcuts {
+  width: 14px;
+  height: 14px;
+  /* Better vertical centering of the icon */
+  margin-top: -2px;
 }
 
 .scopes-content .toggle-map-scopes a.mdn {
-  padding-inline-end: 10px;
+  padding-inline-start: 3px;
 }
 
 .scopes-content .toggle-map-scopes .img.shortcuts {
   background: var(--theme-comment);
 }
 
-.scopes-content .toggle-map-scopes {
-  display: flex;
-  align-items: center;
-}
-
 .object-node.default-property {
   opacity: 0.6;
 }
 
 .object-node {
   padding-left: 4px;
 }
 
--- a/devtools/client/debugger/new/src/components/SecondaryPanes/Scopes.js
+++ b/devtools/client/debugger/new/src/components/SecondaryPanes/Scopes.js
@@ -1,43 +1,37 @@
 /* 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 { isGeneratedId } from "devtools-source-map";
 import { connect } from "../../utils/connect";
-import { features } from "../../utils/prefs";
 import actions from "../../actions";
 import { createObjectClient } from "../../client/firefox";
 
 import {
   getSelectedSource,
   getSelectedFrame,
   getGeneratedFrameScope,
   getOriginalFrameScope,
   getIsPaused,
   getPauseReason,
   getMapScopes,
   getCurrentThread
 } from "../../selectors";
 import { getScopes } from "../../utils/pause/scopes";
 
 import { objectInspector } from "devtools-reps";
-import AccessibleImage from "../shared/AccessibleImage";
 
 import type { Why } from "../../types";
 import type { NamedValue } from "../../utils/pause/scopes/types";
 
 import "./Scopes.css";
 
-const mdnLink =
-  "https://developer.mozilla.org/en-US/docs/Tools/Debugger/Using_the_Debugger_map_scopes_feature";
-
 const { ObjectInspector } = objectInspector;
 
 type Props = {
   isPaused: boolean,
   selectedFrame: Object,
   generatedFrameScopes: Object,
   originalFrameScopes: Object | null,
   isLoading: boolean,
@@ -106,44 +100,16 @@ class Scopes extends PureComponent<Props
       });
     }
   }
 
   onToggleMapScopes = () => {
     this.props.toggleMapScopes();
   };
 
-  renderMapScopes() {
-    const { selectedFrame, shouldMapScopes } = this.props;
-
-    if (
-      !features.mapScopes ||
-      !selectedFrame ||
-      isGeneratedId(selectedFrame.location.sourceId)
-    ) {
-      return null;
-    }
-
-    return (
-      <div className="toggle-map-scopes" onClick={this.onToggleMapScopes}>
-        <input
-          type="checkbox"
-          checked={shouldMapScopes ? "checked" : ""}
-          onChange={e => e.stopPropagation() && this.onToggleMapScopes()}
-        />
-        <div className="toggle-map-scopes-label">
-          <span>{L10N.getStr("scopes.mapScopes")}</span>
-        </div>
-        <a className="mdn" target="_blank" href={mdnLink}>
-          <AccessibleImage className="shortcuts" />
-        </a>
-      </div>
-    );
-  }
-
   renderScopesList() {
     const {
       isPaused,
       isLoading,
       openLink,
       openElementInInspector,
       shouldMapScopes
     } = this.props;
@@ -161,30 +127,16 @@ class Scopes extends PureComponent<Props
             autoExpandDepth={1}
             disableWrap={true}
             dimTopLevelWindow={true}
             openLink={openLink}
             createObjectClient={grip => createObjectClient(grip)}
             onDOMNodeClick={grip => openElementInInspector(grip)}
             onInspectIconClick={grip => openElementInInspector(grip)}
           />
-          {originalScopes && shouldMapScopes ? (
-            <div className="scope-type-toggle">
-              <button
-                onClick={e => {
-                  e.preventDefault();
-                  this.setState({ showOriginal: !showOriginal });
-                }}
-              >
-                {showOriginal
-                  ? L10N.getStr("scopes.toggleToGenerated")
-                  : L10N.getStr("scopes.toggleToOriginal")}
-              </button>
-            </div>
-          ) : null}
         </div>
       );
     }
 
     let stateText = L10N.getStr("scopes.notPaused");
     if (isPaused) {
       if (isLoading) {
         stateText = L10N.getStr("loadingText");
@@ -196,22 +148,17 @@ class Scopes extends PureComponent<Props
     return (
       <div className="pane scopes-list">
         <div className="pane-info">{stateText}</div>
       </div>
     );
   }
 
   render() {
-    return (
-      <div className="scopes-content">
-        {this.renderMapScopes()}
-        {this.renderScopesList()}
-      </div>
-    );
+    return <div className="scopes-content">{this.renderScopesList()}</div>;
   }
 }
 
 const mapStateToProps = state => {
   const thread = getCurrentThread(state);
   const selectedFrame = getSelectedFrame(state, thread);
   const selectedSource = getSelectedSource(state);
 
--- a/devtools/client/debugger/new/src/components/SecondaryPanes/index.js
+++ b/devtools/client/debugger/new/src/components/SecondaryPanes/index.js
@@ -1,26 +1,29 @@
 /* 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, { Component } from "react";
+import { isGeneratedId } from "devtools-source-map";
 import { connect } from "../../utils/connect";
 import { List } from "immutable";
 
 import actions from "../../actions";
 import {
   getTopFrame,
   getBreakpointsList,
   getBreakpointsDisabled,
   getBreakpointsLoading,
   getExpressions,
   getIsWaitingOnBreak,
+  getMapScopes,
+  getSelectedFrame,
   getShouldPauseOnExceptions,
   getShouldPauseOnCaughtExceptions,
   getWorkers,
   getCurrentThread
 } from "../../selectors";
 
 import AccessibleImage from "../shared/AccessibleImage";
 import { prefs, features } from "../../utils/prefs";
@@ -35,17 +38,17 @@ import CommandBar from "./CommandBar";
 import UtilsBar from "./UtilsBar";
 import XHRBreakpoints from "./XHRBreakpoints";
 import EventListeners from "./EventListeners";
 
 import Scopes from "./Scopes";
 
 import "./SecondaryPanes.css";
 
-import type { Expression, WorkerList } from "../../types";
+import type { Expression, Frame, WorkerList } from "../../types";
 
 type AccordionPaneItem = {
   header: string,
   component: any,
   opened?: boolean,
   onToggle?: () => void,
   shouldOpen?: () => boolean,
   buttons?: any
@@ -69,29 +72,35 @@ type State = {
   showXHRInput: boolean
 };
 
 type Props = {
   expressions: List<Expression>,
   hasFrames: boolean,
   horizontal: boolean,
   breakpoints: Object,
+  selectedFrame: ?Frame,
   breakpointsDisabled: boolean,
   breakpointsLoading: boolean,
   isWaitingOnBreak: boolean,
+  shouldMapScopes: boolean,
   shouldPauseOnExceptions: boolean,
   shouldPauseOnCaughtExceptions: boolean,
   workers: WorkerList,
   toggleShortcutsModal: () => void,
   toggleAllBreakpoints: typeof actions.toggleAllBreakpoints,
+  toggleMapScopes: typeof actions.toggleMapScopes,
   evaluateExpressions: typeof actions.evaluateExpressions,
   pauseOnExceptions: typeof actions.pauseOnExceptions,
   breakOnNext: typeof actions.breakOnNext
 };
 
+const mdnLink =
+  "https://developer.mozilla.org/docs/Tools/Debugger/Using_the_Debugger_map_scopes_feature?utm_source=devtools&utm_medium=debugger-map-scopes";
+
 class SecondaryPanes extends Component<Props, State> {
   constructor(props: Props) {
     super(props);
 
     this.state = {
       showExpressionsInput: false,
       showXHRInput: false
     };
@@ -203,22 +212,61 @@ class SecondaryPanes extends Component<P
   }
 
   getScopeItem(): AccordionPaneItem {
     return {
       header: L10N.getStr("scopes.header"),
       className: "scopes-pane",
       component: <Scopes />,
       opened: prefs.scopesVisible,
+      buttons: this.getScopesButtons(),
       onToggle: opened => {
         prefs.scopesVisible = opened;
       }
     };
   }
 
+  getScopesButtons() {
+    const { selectedFrame, shouldMapScopes } = this.props;
+
+    if (
+      !features.mapScopes ||
+      !selectedFrame ||
+      isGeneratedId(selectedFrame.location.sourceId)
+    ) {
+      return null;
+    }
+
+    return [
+      <div>
+        <label
+          className="map-scopes-header"
+          title={L10N.getStr("scopes.mapping.label")}
+          onClick={e => e.stopPropagation()}
+        >
+          <input
+            type="checkbox"
+            checked={shouldMapScopes ? "checked" : ""}
+            onChange={e => this.props.toggleMapScopes()}
+          />
+          {L10N.getStr("scopes.map.label")}
+        </label>
+        <a
+          className="mdn"
+          target="_blank"
+          href={mdnLink}
+          onClick={e => e.stopPropagation()}
+          title={L10N.getStr("scopes.helpTooltip.label")}
+        >
+          <AccessibleImage className="shortcuts" />
+        </a>
+      </div>
+    ];
+  }
+
   getWatchItem(): AccordionPaneItem {
     return {
       header: L10N.getStr("watchExpressions.header"),
       className: "watch-expressions-pane",
       buttons: this.watchExpressionHeaderButtons(),
       component: (
         <Expressions
           showInput={this.state.showExpressionsInput}
@@ -410,30 +458,34 @@ class SecondaryPanes extends Component<P
         {this.renderUtilsBar()}
       </div>
     );
   }
 }
 
 const mapStateToProps = state => {
   const thread = getCurrentThread(state);
+
   return {
     expressions: getExpressions(state),
     hasFrames: !!getTopFrame(state, thread),
     breakpoints: getBreakpointsList(state),
     breakpointsDisabled: getBreakpointsDisabled(state),
     breakpointsLoading: getBreakpointsLoading(state),
     isWaitingOnBreak: getIsWaitingOnBreak(state, thread),
+    selectedFrame: getSelectedFrame(state, thread),
+    shouldMapScopes: getMapScopes(state),
     shouldPauseOnExceptions: getShouldPauseOnExceptions(state),
     shouldPauseOnCaughtExceptions: getShouldPauseOnCaughtExceptions(state),
     workers: getWorkers(state)
   };
 };
 
 export default connect(
   mapStateToProps,
   {
     toggleAllBreakpoints: actions.toggleAllBreakpoints,
     evaluateExpressions: actions.evaluateExpressions,
     pauseOnExceptions: actions.pauseOnExceptions,
+    toggleMapScopes: actions.toggleMapScopes,
     breakOnNext: actions.breakOnNext
   }
 )(SecondaryPanes);
--- a/devtools/client/locales/en-US/debugger.properties
+++ b/devtools/client/locales/en-US/debugger.properties
@@ -686,23 +686,26 @@ scopes.header=Scopes
 # LOCALIZATION NOTE (scopes.notAvailable): Scopes right sidebar pane message
 # for when the debugger is paused, but there isn't pause data.
 scopes.notAvailable=Scopes unavailable
 
 # LOCALIZATION NOTE (scopes.notPaused): Scopes right sidebar pane message
 # for when the debugger is not paused.
 scopes.notPaused=Not paused
 
-# LOCALIZATION NOTE (scopes.toggleToGenerated): Link displayed in the right
-# sidebar scope pane to update the view to show generated scope data.
-scopes.toggleToGenerated=Show generated scope
+# LOCALIZATION NOTE (scopes.mapping.label): Scopes right sidebar pane
+# tooltip for checkbox and label
+scopes.mapping.label=Map original variable names
 
-# LOCALIZATION NOTE (scopes.toggleToOriginal): Link displayed in the right
-# sidebar scope pane to update the view to show original scope data.
-scopes.toggleToOriginal=Show original scope
+# LOCALIZATION NOTE (scopes.helpTooltip.label): Scopes right sidebar pane
+# icon tooltip for link to MDN
+scopes.helpTooltip.label=Learn more about map scopes
+
+# LOCALIZATION NOTE (scopes.map.label): Checkbox label to map scopes
+scopes.map.label=Map
 
 # LOCALIZATION NOTE (scopes.block): Refers to a block of code in
 # the scopes pane when the debugger is paused.
 scopes.block=Block
 
 # LOCALIZATION NOTE (sources.header): Sources left sidebar header
 sources.header=Sources